程序员Android开发

android +j2ee实现JSSE的通信

2017-05-27  本文已影响0人  Rhett_S

JSSE(JAVA安全套接字扩展,JAVA Secure Socket Extension)是SSL和TLS的纯Java实现,,通过它可以透明地提供数据加密、服务器认证、信息完整性等功能,就像使用普通的套接字一样使用安全套接字。

开始前的准备

密钥格式

SSL/TLS协议通信就必须涉及到密钥和数字证书。
在Java支持JKS,JCEKS和PKCS#12格式的密钥。但是android不支持JKS,如果入到JKS文件,我们可以把他转换为BKS文件。

JKS文件(通常为.jks或.keystore,扩展名无关)可以通过Java原生工具——KeyTool生成;
JCKES文件也是JAVA中常用的密钥格式。JKS的Provider是SUN,在每个版本的JDK中都有,JCEKS的Provider是SUNJCE,1.4后我们都能够直接使用它。
PKCS#12文件(通常为.p12或.pfx,意味个人信息交换文件),可以通过OpenSSL工具产生。
BKS文件是android单独支持的文件。可以和JKS文件转换。

文件之间的关系


.cer格式文件俗称证书,但这个证书中没有私钥,只包含了公钥;
.pfx格式文件不仅包含了公钥,还包含了私钥,当然这个私钥是加密的,不输入密码是解不了密的;
.jks格式文件表示java密钥存储器(javakey store),它可以同时容纳N个公钥跟私钥,是一个密钥库;
.keystore格式文件其实跟.jks基本是一样的;
.truststore格式文件表示信任证书存储库,它和.keystore是一样的。仅仅包含了通信对方的公钥,当然你可以直接把通信对方的jks作为信任库。

使用SSL/TLS协议通信,如果是双向认证的话,则需要客户端和服务端各自有一组自己的密钥(keyStore)以及信任文件(trustStore),当然可以使用keyStore代替trustStore免去证书相互导入的麻烦。java中的类图如下(这里的keyStore是JDK中的keyStore。android内部也有一个keyStore,这里不去管它)

UML

证书

keytool -validity 365 -genkey -v -alias server -keyalg RSA -keystore E:\test1\T1\server.keystore -dname "CN=192.168.0.036,OU=rongyiwang,O=rongyiwang,L=Shanghai,ST=Shanghai,c=cn" -storepass 123456 -keypass 123456
keytool -validity 365 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore E:\test1\T1\client.p12 -dname "CN=client,OU=rongyiwang,O=rongyiwang,L=Shanghai,ST=Shanghai,c=cn" -storepass 123456 -keypass 123456
keytool -export -v -alias client -keystore E:\test1\T1\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file E:\test1\T1\client.cer
keytool -export -v -alias server -keystore E:\test1\T1\server.keystore -storepass 123456 -rfc -file E:\test1\T1\server.cer
keytool -import -v -alias server -file E:\test1\T1\server.cer -keystore E:\test1\T1\client.truststore -storepass 123456 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
keytool -import -v -alias client -file E:\test1\T1\client.cer -keystore E:\test1\T1\serverytrust.keystore -storepass 123456
keytool -list -keystore E:\test1\T1\server.keystore -storepass 123456

服务端

首先加载自己的密钥和信任密钥
1.keyStore


           KeyStore serverKeyStore = KeyStore.getInstance("JKS");  
           serverKeyStore.load(new FileInputStream(serverKeyStoreFile), serverKeyStorePwd.toCharArray());  

2.trustStore


           KeyStore serverTrustKeyStore = KeyStore.getInstance("JKS");  
           serverTrustKeyStore.load(new FileInputStream(serverTrustKeyStoreFile), serverTrustKeyStorePwd.toCharArray());  

3.建立SSLServerSocket

           KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  
           kmf.init(serverKeyStore, catServerKeyPwd.toCharArray());  
     
           TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  
           tmf.init(serverTrustKeyStore);  
     
           SSLContext sslContext = SSLContext.getInstance("TLSv1.2");  
           sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  
     
           SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();  
           SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(18080);  
           sslServerSocket.setNeedClientAuth(true);  

4.到了这里基本就和不同Socket编程差不多了,监听SSLServerSocket即可

 while (true){
        SSLSocket s = (SSLSocket) sslServerSocket.accept();
         if(s!=null){
            // do something
         }
}

客户端

上一篇 下一篇

猜你喜欢

热点阅读