ssl/https/wss总结

概念性的东西就不说了,自己去查一下,这里只实践

1. OpenSSL与Java KeyTool的证书

1.1 OpenSSL生成证书的方式总结:

openssl基本原理 + 生成证书 + 使用实例 -这篇很精华,就是格式太差,谁让CSDN没有markdown呢...
如何使用OpenSSL工具生成根证书与应用证书 - 这篇注解写的比较详细
使用OpenSSL API 建立SSL安全通信的一般流程
OpenSSL客户端服务器实例下载 - 使用SSL通信的C++客户端与服务器聊天程序,需要配置OpenSSL的Lib库

1.2 Java KeyTool的使用

JDK 中的证书生成和管理工具 keytool
Java HTTPS客户端如何处理证书 - 这篇文章非常好,关于Java端ssl的使用,基本上看这一篇就够了

1.3 Openssl与Java keytool生成证书的转换

keytool和openssl生成的证书转换

2.Java客户端发送https请求

可参考我之前的一篇总结性文章:
Nginx配置https Java代码单向验证 -包含客户端验证服务器证书与不验证服务器证书两种连接方式

3. Java发送wss(Secure Websocket)请求

3.1 Java-Websocket.jar

java WebSocket的实现以及Spring WebSocket -这篇文章讲了Java各种对WebSocket的实现
然而,上面文章里的实现并不怎么好用,我项目中用的是Java-Websocket的实现:
github地址
Maven仓库地址

3.2 java的websocket客户端连接C++的SSL服务器(单向验证)

Java-Websocket的代码中有对SSL的实现示例,是一个客户端与服务器双向验证的例子,但是用的是同个keystore与truststore
参考Java HTTPS客户端如何处理证书这篇文章中的单向验证部分

server侧只需要自己的keystore文件,不需要truststore文件
client侧不需要自己的keystore文件,只需要truststore文件(其中包含server的公钥)
此外server侧需要在创建SSLServerSocket之后设定不需要客户端证书:setNeedClientAuth(false)

C++客户端与服务器代码上面的链接中都有,这里关键的问题是两点:

  • Java使用的是jks格式的证书,C++使用的是pem格式的,双方是否能连通?(理论上没问题,经验证也没问题)
  • Java使用的keystore与truststore与C++的证书,私钥有什么对应关系?
    • keystore中一般保存的是我们的私钥,用来加解密或者为别人做签名,通过它可以导出证书
    • truststore保存的是可信任的证书

我们用OpenSSL来生成证书与私钥,PEM格式证书转换为jks文件:

转换为pkcs12格式:

~/tmp/cert# openssl pkcs12 -export -in public.crt -inkey private.pem -out server.p12 -name server -passin pass:${passwd} -passout pass:${passwd}
~/tmp/cert# ll
total 16
-rw-r--r-- 1 root root  664 Jun 14 20:43 cert.csr
-rw-r--r-- 1 root root  963 Jun 14 20:27 private.pem
-rw-r--r-- 1 root root  871 Jun 14 20:44 public.crt
-rw-r--r-- 1 root root 1682 Jun 14 20:55 server.p12

导入到jks中:

~/tmp/cert# keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass ${passwd} -alias server -deststorepass ${passwd} -destkeypass ${passwd} -destkeystore ServerCert.jks
~/tmp/cert# ll
total 20
-rw-r--r-- 1 root root  664 Jun 14 20:43 cert.csr
-rw-r--r-- 1 root root  963 Jun 14 20:27 private.pem
-rw-r--r-- 1 root root  871 Jun 14 20:44 public.crt
-rw-r--r-- 1 root root 1372 Jun 14 20:57 ServerCert.jks
-rw-r--r-- 1 root root 1682 Jun 14 20:55 server.p12

Java-Websocket客户端代码:

    public static void SSLTestSingle1()throws Exception {
        WebSocketChatClient chatclient = new WebSocketChatClient( new URI( "wss://localhost:8443" ) );


        // load up the key store
        String STORETYPE = "JKS";
        String KEYSTORE = "foxclienttrust.keystore";
        String STOREPASSWORD = "foxclienttrustks";

        KeyStore ks = KeyStore.getInstance( STORETYPE );
        File kf = new File( KEYSTORE );
        ks.load( new FileInputStream( kf ), STOREPASSWORD.toCharArray() );

//      KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
//      kmf.init( ks, KEYPASSWORD.toCharArray() );
        TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );
        tmf.init( ks );

        SSLContext sslContext = null;
        sslContext = SSLContext.getInstance( "TLS" );
        sslContext.init( null, tmf.getTrustManagers(), null );
        // sslContext.init( null, null, null ); // will use java's default key and trust store which is sufficient unless you deal with self-signed certificates

        SSLSocketFactory factory = sslContext.getSocketFactory();// (SSLSocketFactory) SSLSocketFactory.getDefault();

        chatclient.setSocket( factory.createSocket() );


        chatclient.connectBlocking();

        BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
        while ( true ) {
            String line = reader.readLine();
            if( line.equals( "close" ) ) {
                chatclient.close();
            } else {
                chatclient.send( line );
            }
        }
    }

你可能感兴趣的:(ssl/https/wss总结)