Java Swing <--> Tomcat SSL 服务端-客户端双向认证

本文详细介绍了使用SSL双向认证在Java客户端发送HTTPS信息的过程,包括生成服务器端和客户端证书库、导入信任库、配置tomcat及Java代码实现。重点在于客户端信任库、私钥库的管理,以及tomcat配置与Java代码调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

环境:

jdk1.6.0_26  + tomCat6.0_18  |   tomCat 5.5.23 测试成功

------------------------
1 服务器端 生成密码库
------------------------

E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -validity 36500 -genkey -v -alias server -keyalg RSA -keystore "D:\server.keystore" -dname "CN=127.0.0.1,OU=pushworld,O=pushworld,L=ChaoYang,ST=BeiJing,c=CN" -storepass pushworld -keypass pushworld

执行结果:
 
 正在为以下对象生成 1,024 位 RSA 密钥对和自签名证书 (SHA1withRSA)(有效期为 36,500 天):
         CN=127.0.0.1, OU=pushworld, O=pushworld, L=ChaoYang, ST=BeiJing, C=CN
 [正在存储 D:\server.keystore]

------------------------------------------------------------------------------------------------------------
2 利用服务器端 证书库 导出 服务器证书
------------------------------------------------------------------------------------------------------------
E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -export -v -alias server -keystore D:\server.keystore -storepass pushworld -rfc -file  D:\server.cer
 
 执行结果:
          保存在文件中的认证 <D:\server.cer>
------------------------
3 为 客户端 生成密码库
------------------------

E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -validity 36500 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore "D:\client.p12" -dname "CN=Client,OU=pushworld,O=pushworld,L=ChaoYang,ST=BeiJing,c=CN" -storepass pushworld -keypass pushworld

执行结果:
 
    正在为以下对象生成 1,024 位 RSA 密钥对和自签名证书 (SHA1withRSA)(有效期为 36,500 天):
         CN=Client, OU=pushworld, O=pushworld, L=ChaoYang, ST=BeiJing, C=CN
    [正在存储 D:\client.p12]

------------------------------------------------------------------------------------------------------------
4 利用客户端 证书库 导出客户端证书
------------------------------------------------------------------------------------------------------------
E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -export -v -alias client -storetype PKCS12  -keystore D:\client.p12  -storepass pushworld -rfc -file  D:\client.cer
 
 执行结果:
          保存在文件中的认证 <D:\client.cer>        
       
------------------------------------------------------------------------------------------------------------
5 利用服务器端证书 生成客户端信任证书库
------------------------------------------------------------------------------------------------------------
E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -import -v -alias server  -file D:\server.cer -keystore d:\client.truststore -storepass pushworld

执行结果:
         所有者:CN=127.0.0.1, OU=pushworld, O=pushworld, L=ChaoYang, ST=BeiJing, C=CN
         签发人:CN=127.0.0.1, OU=pushworld, O=pushworld, L=ChaoYang, ST=BeiJing, C=CN
         序列号:50a20be3
         有效期: Tue Nov 13 16:59:15 CST 2012 至Thu Oct 20 16:59:15 CST 2112
         证书指纹:
                  MD5:7B:65:CC:03:8E:C9:3E:79:27:7C:72:4B:BD:DD:C8:FC
                  SHA1:6E:B2:04:9B:CB:3F:8A:7E:BD:12:AE:74:00:42:28:AA:BB:D6:B3:0E
                  签名算法名称:SHA1withRSA
                  版本: 3
         信任这个认证? [否]:  Y
         认证已添加至keystore中
         [正在存储 d:\client.truststore]

------------------------------------------------------------------------------------------------------------
6 将客户端证书 导入到 服务器的证书库中去
------------------------------------------------------------------------------------------------------------

E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -import -v -alias client  -file D:\client.cer -keystore d:\server.keystore -storepass pushworld

执行结果:

         所有者:CN=Client, OU=pushworld, O=pushworld, L=ChaoYang, ST=BeiJing, C=CN
         签发人:CN=Client, OU=pushworld, O=pushworld, L=ChaoYang, ST=BeiJing, C=CN
         序列号:50a20c30
         有效期: Tue Nov 13 17:00:32 CST 2012 至Thu Oct 20 17:00:32 CST 2112
         证书指纹:
                  MD5:DC:06:77:E7:86:F9:4C:C2:7F:3C:66:4A:70:62:C6:70
                  SHA1:9A:6A:6D:89:A9:29:E1:2E:C7:62:DF:0F:76:F7:C3:1C:6C:27:8F:C2
                  签名算法名称:SHA1withRSA
                  版本: 3
         信任这个认证? [否]:  Y
         认证已添加至keystore中
         [正在存储 d:\server.keystore]
------------------------------------------------------------------------------------------------------------
7 查看下 证书库中的全部证书
------------------------------------------------------------------------------------------------------------       
        
E:\Wanglei\SSL\jdk1.6.0_26\bin>

keytool -list -keystore d:/server.keystore -storepass pushworld

执行结果:
          Keystore 类型: JKS
          Keystore 提供者: SUN

          您的 keystore 包含 2 输入

          client, 2012-11-13, trustedCertEntry,
          认证指纹 (MD5): DC:06:77:E7:86:F9:4C:C2:7F:3C:66:4A:70:62:C6:70
          server, 2012-11-13, PrivateKeyEntry,
          认证指纹 (MD5): 7B:65:CC:03:8E:C9:3E:79:27:7C:72:4B:BD:DD:C8:FC


---------------------------------------------------------------------------------------------------------------------
需要的 单项认证   客户端需要 信任库 d:\client.truststore 已经存在了。 
       双向认证   客户端还需要 私钥 d:\client.p12   也有了。
     
       不同的 tomCat 版本参数有所不同,大家努力测试吧。 我在测试下 tomCat5.5.23 这个一直没成功过
     
       tomCat 配置  conf/server.xml  配置 tomCat6.0_18 测试成功的
---------------------------------------------------------------------------------------------------------------------

<Connector port="8443"  SSLEnabled="true"
         
                 maxThread="150" scheme="https" secure="true" enableLookups="false" minProcessors="5" maxProcessors="75"

                 acceptCount="100"  disableUploadTimeout="true" sslprotocol="TLS"
  
                 clientAuth="true"   <!-- false 单项认证 ,true 双向认证-->

                 keystoreFile="D:/server.keystore" keystorePass="pushworld"    <!-- 服务端的认证库 ,密码 -->

                 truststoreFile="D:/server.keystore" truststorePass="pushworld"    <!-- 客户端的信任库 ,密码 已经通过client.cer 导进来了-->

                 />

-----------------------------------------------------------------------------------------------------------------------

tomCat 5.5.23 测试成功的 需要添加下面一个参数
   protocol="org.apache.coyote.http11.Http11Protocol" 

-----------------------------------------------------------------------------------------------------------------------


java 代码
-----------------------------------------------------------------------------------------------------------------------
package cn.com.ssl.oneway;

import java.io.BufferedReader;  
import java.io.InputStreamReader;  
import java.io.OutputStream;  
import java.net.URL;  
import javax.net.ssl.HostnameVerifier;  
import javax.net.ssl.HttpsURLConnection;  
import javax.net.ssl.SSLSession;  

/***
 *
 * @author wanglei
 * @update 2012-11-13
 * 客户端单项 发送https信息 这里只是需要 客户端发送
 */
 
public class ClientSendData {  
   
    // 客户端信任的证书  
    private String sslTrustStore;  
    private String sslTrustStorePassword;  
    private String Url; 
   
    //客户端密钥库  
    private String sslKeyStorePath;  
    private String sslKeyStorePassword;  
    private String sslKeyStoreType;  
    //初始化数据  
    public ClientSendData() {
     
     //客户端信任库 这样就不会像IE 那样 提示不受信任了, ie7 8 9 地址连就是红色的
        sslTrustStore = "D://client.truststore";  
        sslTrustStorePassword = "pushworld";  
        Url = "https://192.168.0.33:8443/igrc/login"; 
       
        //设置系统参数    有了 这些参数 系统就会 默认进行证书的管理了
        System.setProperty("javax.net.ssl.trustStore", sslTrustStore);  
        System.setProperty("javax.net.ssl.trustStorePassword", sslTrustStorePassword);  
        System.setProperty("java.protocol.handler.pkgs","sun.net.www.protocol");
       
        //双向认证时的参数
        sslKeyStorePath = "D://client.p12";  
        sslKeyStorePassword  = "pushworld";  
        sslKeyStoreType = "PKCS12"; //密钥库类型,有JKS PKCS12等  
       
       
        System.setProperty("javax.net.ssl.keyStore", sslKeyStorePath);  
        System.setProperty("javax.net.ssl.keyStorePassword",sslKeyStorePassword);  
        System.setProperty("javax.net.ssl.keyStoreType", sslKeyStoreType); 
       
    }  
 
    public String sendData(String _sendData) {  
        StringBuffer receivedData = new StringBuffer();  
        try {  
          
           
            HttpsURLConnection connection = getHttpsURLConnection(Url);  
           
            //发送数据
            connection.setRequestProperty("Content-Type", "text/xml");  
            connection.setDoOutput(true);  
            connection.setDoInput(true);  
            connection.setRequestMethod("POST");  
            connection.setUseCaches(false);  
            connection.setReadTimeout(30000);  

            byte data[] = _sendData.getBytes();  
            OutputStream out = connection.getOutputStream();  
            out.write(data);  
            //开始接收 返回来的信息
            InputStreamReader inReader = new InputStreamReader(connection.getInputStream(), "GBK");  
            BufferedReader aReader = new BufferedReader(inReader);  
            String aLine;  
            while ((aLine = aReader.readLine()) != null) {  
                receivedData.append(aLine);  
            }  
            //打印状态
            aReader.close();  
            connection.disconnect(); 
           
        } catch (Exception e) {  
            e.printStackTrace();  
        } 
       
        return receivedData.toString(); 
       
    }  
    /**
     * 与服务器建立连接
     * 至于证书的管理 系统参数已经设置好
     * 这里 每次连接的时候都 进行了验证
     */
    public HttpsURLConnection getHttpsURLConnection(String sendurl)   throws Exception {  
      
     URL url = new URL(sendurl);  
     
     //
        HostnameVerifier hv = new HostnameVerifier() {  
            public boolean verify(String urlHostName, SSLSession session) {  
                return true;  
            }  
        };  
        HttpsURLConnection.setDefaultHostnameVerifier(hv);  
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();  
        return connection;
    }  
 
    public static void main(String[] args) {  
        ClientSendData t = new ClientSendData();
       
       String retemp = t.sendData("-------------------"); 
       System.out.println("返回信息:\r\n"+retemp);
      
       retemp = t.sendData("-------------------"); 
       System.out.println("返回信息:\r\n"+retemp);
     
    }  

----------------------------------------------------------------------------------------------------------------------------------------------------

相关资料:

java web 项目的双向认证案例

http://www.blogjava.net/icewee/archive/2012/06/04/379947.html

https 原理说明 用户证书信任管理器

http://www.cnblogs.com/devinzhang/archive/2012/02/28/2371631.html

java 双向验证 客户端代码 案例

http://zhuyuehua.iteye.com/blog/1122444

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值