生成服务器密钥库和证书,客户端导入服务器证书:
1、生成密钥库(自签名的证书和私钥)
keytool -genkey -alias sksalias -keyalg RSA -keystore skeystore.jks
密钥库和密钥库别名都需要密码,用时也需要
Enter keystore password:
Enter key password for <ksalias>
查看密钥库
keytool -list -v -keystore skeystore.jks
2、导出密钥库公钥、信息等到证书中
keytool -export -alias sksalias -keystore skeystore.jks -storepass 123456 -file scert.cer
3、建立信任密钥库(将服务端证书,导入到客户端的信任密钥库中)
keytool -import -alias sksalias -file scert.cer -keystore ctruststore
信任密钥库truststore也需要密码,但别名不需要密码
//truststore也是密钥库,只是少了私钥
Enter keystore password:
查看信任密钥库
keytool -list -v -keystore truststore
keytool,可以转换,pem,直接导入pem的。ie,firefox也可以转换。
同理,生成客户端的密钥库和证书,服务器端导入客户端证书。
keytool -genkey -alias cksalias -keyalg RSA -keystore ckeystore.jks
keytool -export -alias cksalias -keystore ckeystore.jks -storepass 123456 -file ccert.cer
keytool -import -alias cksalias -file ccert.cer -keystore struststore
代码如下
package socket.ssl.mutual; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManagerFactory; public class SecureServerDemo { public static void main(String[] args) { SSLServerSocket server = null; String hello = "Hello World!---shuangxiangrenzheng"; try { server = getSSLServerSocket(); // server.setNeedClientAuth(true); } catch (Exception e) { e.printStackTrace(); System.exit(1); } while(true) { try { System.out.println("before accept..."); SSLSocket cs = (SSLSocket)server.accept(); System.out.println("begin accept..."); OutputStream out = cs.getOutputStream(); DataOutputStream dos = new DataOutputStream(out); dos.writeUTF(hello); out.close(); cs.close(); } catch (IOException e) { e.printStackTrace(); } } } static SSLServerSocket getSSLServerSocket() throws Exception{ SSLContext ctx = SSLContext.getInstance("SSL"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); KeyStore ks = KeyStore.getInstance("JKS"); KeyStore tks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("D:/ssl/jks2/skeystore.jks"), "123456".toCharArray()); tks.load(new FileInputStream("D:/ssl/jks2/truststore"), "123456".toCharArray()); kmf.init(ks, "123456".toCharArray()); tmf.init(tks); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLServerSocket serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(8090); serverSocket.setNeedClientAuth(true); // serverSocket.setn return serverSocket; } }
package socket.ssl.mutual;
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.UnknownHostException; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; public class SecureClientDemo { public static void main(String[] args) { try { SSLSocket s = getSSLSocket(); InputStream in = null; in = s.getInputStream(); DataInputStream dis = new DataInputStream(in); try{ String st = dis.readUTF(); System.out.println(st); } catch (Exception e) { e.printStackTrace(); } in.close(); s.close(); System.out.println("-------------------"); } catch (Exception e) { e.printStackTrace(); } } static SSLSocket getSSLSocket() throws Exception{ SSLContext ctx = SSLContext.getInstance("SSL"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); KeyStore ks = KeyStore.getInstance("JKS"); KeyStore tks = KeyStore.getInstance("JKS"); // ks.load(new FileInputStream("D:/ssl/jks2/ckeystore2.jks"), "123456".toCharArray()); // tks.load(new FileInputStream("D:/ssl/jks2/ckeystore2.jks"), "123456".toCharArray()); ks.load(new FileInputStream("D:/ssl/jks2/ckeystore.jks"), "123456".toCharArray()); tks.load(new FileInputStream("D:/ssl/jks2/ckeystore.jks"), "123456".toCharArray()); kmf.init(ks, "123456".toCharArray()); tmf.init(tks); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLSocket sSLSocket = (SSLSocket)ctx.getSocketFactory().createSocket("127.0.0.1", 8090); sSLSocket.startHandshake(); return sSLSocket; } }
1,用回调syslof4j的getsocket,然后socket.handshake,会卡死
2,用这个测试,也会卡死,必须server端,先开始handshake才行,或者他们之间发送消息(这样测试就会多
一条记录不好),有待深入探讨原因。