使用keytool创建密钥库
使用双向认证的SSL/TLS协议通信,客户端和服务器端都要设置用于证实自己身份的安全证书,并且还要设置信任对方的哪些安全证书。
理论上一共需要准备四个文件,两个keystore文件和两个truststore文件。
通信双方分别拥有一个keystore和一个truststore,keystore用于存放自己的密钥和公钥,truststore用于存放所有需要信任方的公钥。
生成keystore和truststore
首先使用JDK自带的keytool工具来生成keystore和truststore。
- 1)创建server的keystore文件,生成server的公钥/私钥密钥对。需要指定keystore的密码(storepass)和密钥对的密码(keypass)。
访问keystore需要storepass。访问密钥对需要keypass。
|
|
- 2) 创建client的keystore文件。同样需要指定keystore的密码和密钥对的密码。
|
|
- 3)从server的keystore中导出server的证书(其中包括server的公钥)。
|
|
- 4)从client的keystore中导出client的证书(其中包括client的公钥)。
|
|
- 5)创建server的truststore文件并导入client的证书(其中包括client的公钥)。
|
|
- 6)创建client的truststore文件并导入server的证书(其中包括server的公钥)。
|
|
server端处理流程和代码
1)加载server的keystore文件,需要指定keystore的密码(storepass)。
KeyStore类型有如下三种:
jceks - The proprietary keystore implementation provided by the SunJCE provider.
jks - The proprietary keystore implementation provided by the SUN provider.
pkcs12 - The transfer syntax for personal identity information as defined in PKCS #12.2)加载server的truststore文件,需要指定truststore的密码(storepass)。
3)创建KeyManagerFactory对象并用1)中加载的keystore和server密钥对的密码(keypass)来初始化。
4)创建TrustManagerFactory对象并用2)中加载的truststore来初始化。truststore中存的是client的公钥,不需要keypass也可以访问。
5)创建SSLContext并用3)和4)中创建的KeyManagerFactory和TrustManagerFactory对象来初始化。
创建SSLContext是需要给出SSLContext Algorithms。上面这个链接中给出了合法的SSLContext Algorithms,有如下可用值。
SSL - Supports some version of SSL; may support other versions
SSLv2 - Supports SSL version 2 or later; may support other versions
SSLv3 - Supports SSL version 3; may support other versions
TLS - Supports some version of TLS; may support other versions
TLSv1 - Supports RFC 2246: TLS version 1.0 ; may support other versions
TLSv1.1 - Supports RFC 4346: TLS version 1.1 ; may support other versions
TLSv1.2 - Supports RFC 5246: TLS version 1.2 ; may support other versions
6)创建SSLServerSocketFactory,在指定的端口上创建SSLServerSocket并设定需要客户端证书:setNeedClientAuth(true)
7)在SSLServerSocket对象上调用accept()方法等待客户端的连接。
客户端连上来之后这个函数会返回一个SSLSocket对象,在这个对象的输入输出流上进行读写。
在这个SSLSocket对象上可以添加一个HandshakeCompletedListener的监听器,SSL/TLS握手结束后这个监听器的handshakeCompleted方法就会被调用。
客户端有三种方法会触发握手:- 显式调用startHandshake方法
- 在socket对象上进行read或write操作
- 在socket对象上调用getSession方法
代码如下:
client端处理流程和代码
1)加载client的keystore文件。
2)加载client的truststore文件。
3) 创建KeyManagerFactory对象并初始化。
4) 创建TrustManagerFactory对象并初始化。truststore中存的是server的公钥,不需要keypass也可以访问。
5)创建SSLContext并用3)和4)中创建的KeyManagerFactory和TrustManagerFactory对象来初始化。
6)创建SSLSocketFactory,在指定的网络地址和端口上创建SSLSocket。
7)在这个SSLSocket对象的输入输出流上进行读写。
代码如下: