加密方式 | 优缺点 |
---|---|
对称加密 | 加密效率高,密钥在网络中传输不安全 |
非对称加密 | 加密效率低,安全性高,公钥可以在网络中传输 |
防止抵赖,能够检查签名之后内容是否有更改。通过单向散列算法对内容进行求值,相当于对内容进行提取了指纹。
证书颁发机构(相当于所有人都信任的一个中间机构),CA机构也有自已的公钥与私钥。client通过CA机构的公钥与证数中的数字签名来验证证书的合法性。
SSL在网络层所处的位置:
SSL位置
SSL提供的功能:
SSL提供的功能
Keytool 是一个Java 数据证书的管理工具 ,Keytool 将密钥(key)和证书(certificates)存在一个称为keystore的文件中。 在keystore里,包含两种数据: (1)密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥 (2)可信任的证书实体(trusted certificate entries)——只包含公钥 keytool中常用的命令
-genkey 在用户主目录中创建一个默认文件".keystore",(在没有指定生成位置的情况下,keystore会存在用户系统默认目录,如:对于window xp系统,会生成在系统的C:\Documents and Settings\UserName\文件名为“.keystore”)
-alias 产生别名,每个keystore都关联这一个独一无二的alias,这个alias通常不区分大小写
-keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中)
-keyalg 指定密钥的算法 (如 RSA DSA(如果不指定默认采用DSA))
-validity 指定创建的证书有效期多少天
-keysize 指定密钥长度
-storepass 指定密钥库的密码(获取keystore信息所需的密码)
-keypass 指定别名条目的密码
-dname 指定证书拥有者信息
例如: "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码"
-list 显示密钥库中的证书信息
-v 显示密钥库中的证书详细信息
-export 将别名指定的证书导出到文件
keytool -export -alias 需要导出的别名 -keystore 指定keystore -file 指定导出的证书位置及证书名称 -storepass 密码
-file 参数指定导出到文件的文件名
-delete 删除密钥库中某条目
keytool -delete -alias 指定需删除的别名 -keystore 指定keystore -storepass 密码
-printcert 查看导出的证书信息
keytool -printcert -file yushan.crt
-keypasswd 修改密钥库中指定条目口令
keytool -keypasswd -alias 需修改的别名 -keypass 旧密码 -new 新密码 -storepass keystore密码 -keystore
-import 将已签名数字证书导入密钥库
keytool -import -alias 指定导入条目的别名 -keystore 指定keystore -file 需导入的证书
示例1:生成keyStore:
keytool -genkey -v -alias xxx.com -keyalg RSA -keystore D:\STS\live\ssl\src\main\resources\zhiminchen -storepass zhiminchen -keypass zhiminchen -dname "CN=localhost,OU=cn,O=cn,L=cn,ST=cn,C=cn"
示例1:导出证书:
keytool -export -alias xxx.com -keystore D:\S
TS\live\ssl\src\main\resources\zhiminchen -file D:\STS\live\ssl\src\main\resourc
es\zhiminchen.cer -storepass zhiminchen
示例3:导入证书:
keytool -import -trustcacerts -alias xxx.com
-file D:\STS\live\ssl\src\main\resources\zhiminchen.cer -keystore D:\STS\live\ss
l\src\main\resources\client
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
public class SSLServer extends Thread {
private Socket socket;
public SSLServer(Socket socket) {
this.socket = socket;
}
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
String data = reader.readLine();
System.out.println(data);
writer.println(data);
writer.close();
socket.close();
} catch (IOException e) {
}
}
private static String SERVER_KEY_STORE = "D:/STS/live/ssl/src/main/resources/zhiminchen";
private static String SERVER_KEY_STORE_PASSWORD = "zhiminchen";
public static void main(String[] args) throws Exception {
//设置信认的keystore仓库
System.setProperty("javax.net.ssl.trustStore", SERVER_KEY_STORE);
//ssl的上下文
SSLContext context = SSLContext.getInstance("TLS");
KeyStore ks = KeyStore.getInstance("jceks");
//通过KeyStore导入服务端的keystore文件。
ks.load(new FileInputStream(SERVER_KEY_STORE), null);
//这里的SunX509是keystore的文件格式
KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509");
//通过keytool生成是会指定keystore的密码
kf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
context.init(kf.getKeyManagers(), null, null);
ServerSocketFactory factory = context.getServerSocketFactory();
ServerSocket _socket = factory.createServerSocket(8443);
//客服端不需要验证服务端,如果需要验证的话,服务端需要有导入客户端的证书文件
((SSLServerSocket) _socket).setNeedClientAuth(false);
while (true) {
new SSLServer(_socket.accept()).start();
}
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
public class SSLClient {
private static String CLIENT_KEY_STORE = "D:/STS/live/ssl/src/main/resources/client";
public static void main(String[] args) throws Exception {
// 客户端的keystore文件地址
System.setProperty("javax.net.ssl.trustStore", CLIENT_KEY_STORE);
// 输出日志文件,可以看出握手的过程
System.setProperty("javax.net.debug", "ssl,handshake");
SocketFactory sf = SSLSocketFactory.getDefault();
Socket s = sf.createSocket("localhost", 8443);
PrintWriter writer = new PrintWriter(s.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
writer.println("hello");
writer.flush();
System.out.println(reader.readLine());
s.close();
}
}
1) openssl x509 -outform der -in certificate.pem -out certificate.der
2)keytool -import -alias your-alias -keystore cacerts -file certificate.der