• 使用SSLSocket实现双向认证(keytool证书创建双向认证证书(这里有根证书)的详细步骤以及踩雷)


    一、SSL的双向认证步骤以及Keytool的使用方法

      就不再多说,网上一搜一大堆

    二、Keytool创建双向认证证书步骤

      由于收费的CA证书搞不到,平常也用不到,这里只使用了自签名证书。

    1. 创建根证书

    这里直接回车即可。

      2.创建客户端证书以及服务端证书

    服务端

      3.导出客户端以及服务端证书认证请求

    服务端

      4.使用根证书认证客户端以及服务端证书,并生成证书

    服务端

      5.将根证书导入客户端以及服务端密钥库,再将认证后的证书分别导入密钥库。

      此时应先将根证书导入客户端以及服务端密钥库中,不然会报错,这里只演示客户端

    三、客户端以及服务端的身份认证过程代码

    // key store相关信息  
                String keyStoreName = "client.keystore";  
                char[] keyStorePwd = "clientstorepass".toCharArray();  
                char[] keyPwd = keyStorePwd;  
                
                KeyStore keyStore = KeyStore.getInstance("JKS");
                KeyStore trustKeyStore = KeyStore.getInstance("JKS");
                keyStore.load(new FileInputStream("D:\eclipsefiles\cert\"+keyStoreName),keyStorePwd);//必须先加载 keystore 才能对其进行访问
                trustKeyStore.load(new FileInputStream("D:\eclipsefiles\cert\server\server.keystore"),"serverstorepass".toCharArray());
                //创建管理JKS密钥库的X.509密钥管理器
                KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
                kmf.init(keyStore,keyPwd);//使用密钥内容源初始化此工厂。    提供者通常使用 KeyStore 来获取在安全套接字协商期间所使用的密钥内容
                
                TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("SunX509");
                tmFactory.init(trustKeyStore);
                
                //初始sslcontext
    //            SSLContext sslContext=SSLContext.getInstance("SSLv3");
                SSLContext sslContext=SSLContext.getInstance("TLS");
                sslContext.init(kmf.getKeyManagers(),tmFactory.getTrustManagers(),new SecureRandom()); ////trustmanager决定是否信任对方证书
                // 生成套接字
                SSLSocketFactory socketFactory = sslContext.getSocketFactory(); 
                
                socket = (SSLSocket) socketFactory.createSocket("127.0.0.1", 7070); //主机IP地址以及端口
                
                socket.setEnabledCipherSuites(socket.getSupportedCipherSuites());
                socket.setUseClientMode(true);//false设置处于服务器模式
                socket.setEnableSessionCreation( true );

    这里客户端的受信任密钥库是直接使用的服务端的密钥库,也是可行的,但实际上还是应该重新建一个客户端受信任密钥库,里面导入服务端证书以及根证书,例如下面服务端的示例代码

    // key store相关信息  
            String keyStoreName = "server.keystore";  
            char[] keyStorePwd = "serverstorepass".toCharArray();  
            char[] keyPwd = keyStorePwd;  
            KeyStore keyStore = KeyStore.getInstance("JKS");
            KeyStore trustKeyStore = KeyStore.getInstance("JKS");
            keyStore.load(new FileInputStream("D:\eclipsefiles\cert\server\"+keyStoreName),keyStorePwd);//必须先加载 keystore 才能对其进行访问
            trustKeyStore.load(new FileInputStream("D:\eclipsefiles\cert\server\trustserver.keystore"),"trustserverpass".toCharArray());
            
            //创建管理JKS密钥库的X.509密钥管理器
            KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
            kmf.init(keyStore,keyPwd);//使用密钥内容源初始化此工厂。    提供者通常使用 KeyStore 来获取在安全套接字协商期间所使用的密钥内容
            KeyManager[] keyManagers=kmf.getKeyManagers();//Keymanager用于选择自己的安全证书,并发送给对方
            
            TrustManagerFactory tmFactory=TrustManagerFactory.getInstance("SunX509");
            tmFactory.init(trustKeyStore);
            TrustManager[] tManagers=tmFactory.getTrustManagers();//trustmanager决定是否信任对方证书
            
            SSLContext sslContext=SSLContext.getInstance("TLS");
            sslContext.init(keyManagers,tManagers,new SecureRandom());
         
            //根据上面配置的SSL上下文来产生SSLServerSocketFactory,与通常的产生方法不同
            SSLServerSocketFactory factory=sslContext.getServerSocketFactory();
    
            serverSocket=(SSLServerSocket)factory.createServerSocket(7070);
            
            serverSocket.setUseClientMode(false);//设置处于服务器模式,需要向对方出具安全证书
            serverSocket.setNeedClientAuth(true);//设置需要对方的安全证书,否则连接中断
    
            serverSocket.setEnabledCipherSuites(serverSocket.getEnabledCipherSuites());
    由于无法解释的神圣旨意,我们徒然地到处找你;你就是孤独,你就是神秘,比恒河或者日落还要遥远。。。。。。
  • 相关阅读:
    关于position定位
    获取滚动条距离的兼容问题
    margin取百分值
    float 与 display:inline-block
    Object.getOwnPropertyNames()
    正则表达式的方法:replace,match,test(replace参数可以是回调函数)
    offset / scroll / client Left / Top
    client / page / offset / screen X / Y
    原生js贪吃蛇
    Functional PHP 5.3 Part I
  • 原文地址:https://www.cnblogs.com/momoli/p/12762748.html
Copyright © 2020-2023  润新知