欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

java实现 SSL双向认证

发布时间:2024/4/17 编程问答 51 豆豆
生活随笔 收集整理的这篇文章主要介绍了 java实现 SSL双向认证 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

http://avery-leo.iteye.com/blog/276096

实现技术:
JSSE(Java Security Socket Extension)
是Sun为了解决在Internet上的实现安全信息传输的解决方案。它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,可以在Client和Server之间通过TCP/IP协议安全地传输数据。

 


为了实现消息认证。
Server需要:
1)KeyStore: 其中保存服务端的私钥
2)Trust KeyStore:其中保存客户端的授权证书
Client需要:
1)KeyStore:其中保存客户端的私钥
2)Trust KeyStore:其中保存服务端的授权证书

 

使用Java自带的keytool命令,去生成这样信息文件:

1)生成服务端私钥,并且导入到服务端KeyStore文件中

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2)根据私钥,导出服务端证书

 

 

 

3)将服务端证书,导入到客户端的Trust KeyStore中

 

 

采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore中
1)keytool -genkey -alias clientkey -keystore kclient.keystore
2)keytool -export -alias clientkey -keystore kclient.keystore -file client.crt
3)keytool -import -alias clientkey -file client.crt -keystore tserver.keystore

 

 

Server:

 

Java代码  
  • package ssl;  
  •   
  •   
  • import java.io.BufferedInputStream;  
  • import java.io.BufferedOutputStream;  
  • import java.io.FileInputStream;  
  • import java.io.InputStream;  
  • import java.io.OutputStream;  
  • import java.net.Socket;  
  • import java.security.KeyStore;  
  •   
  • import javax.net.ssl.KeyManagerFactory;  
  • import javax.net.ssl.SSLContext;  
  • import javax.net.ssl.SSLServerSocket;  
  • import javax.net.ssl.TrustManagerFactory;  
  •   
  • /** 
  •  * 
  •  * @author Leo 
  •  */  
  • public class Server implements Runnable{  
  •   
  •     private static final int    DEFAULT_PORT                    = 7777;  
  •   
  •     private static final String SERVER_KEY_STORE_PASSWORD       = "123456";  
  •     private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";  
  •   
  •     private SSLServerSocket     serverSocket;  
  •   
  •     /** 
  •      * 启动程序 
  •      *  
  •      * @param args 
  •      */  
  •     public static void main(String[] args) {  
  •         Server server = new Server();  
  •         server.init();  
  •         Thread thread = new Thread(server);  
  •         thread.start();  
  •     }  
  •   
  •     public synchronized void start() {  
  •         if (serverSocket == null) {  
  •             System.out.println("ERROR");  
  •             return;  
  •         }  
  •         while (true) {  
  •             try {  
  •                 Socket s = serverSocket.accept();  
  •                 InputStream input = s.getInputStream();  
  •                 OutputStream output = s.getOutputStream();  
  •   
  •                 BufferedInputStream bis = new BufferedInputStream(input);  
  •                 BufferedOutputStream bos = new BufferedOutputStream(output);  
  •   
  •                 byte[] buffer = new byte[20];  
  •                 bis.read(buffer);  
  •                 System.out.println("------receive:--------"+new String(buffer).toString());  
  •   
  •                 bos.write("yes".getBytes());  
  •                 bos.flush();  
  •   
  •                 s.close();  
  •             } catch (Exception e) {  
  •                 System.out.println(e);  
  •             }  
  •         }  
  •     }  
  •     public void init() {  
  •         try {  
  •             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("src/ssl/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());  
  •             tks.load(new FileInputStream("src/ssl/tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());  
  •   
  •             kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());  
  •             tmf.init(tks);  
  •   
  •             ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  
  •   
  •             serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);  
  •             serverSocket.setNeedClientAuth(true);   
  •         } catch (Exception e) {  
  •             System.out.println(e);  
  •         }  
  •     }  
  •   
  •     public void run() {  
  •         // TODO Auto-generated method stub  
  •         start();  
  •     }  
  • }  
  •  

    Client:

    Java代码  
  • package ssl;  
  •   
  • import java.io.BufferedInputStream;  
  • import java.io.BufferedOutputStream;  
  • import java.io.FileInputStream;  
  • import java.io.IOException;  
  • import java.io.InputStream;  
  • import java.io.OutputStream;  
  • import java.security.KeyStore;  
  •   
  • import javax.net.ssl.KeyManagerFactory;  
  • import javax.net.ssl.SSLContext;  
  • import javax.net.ssl.SSLSocket;  
  • import javax.net.ssl.TrustManagerFactory;  
  •   
  • /** 
  •  * SSL Client 
  •  *  
  •  * @author Leo 
  •  */  
  • public class Client {  
  •   
  •     private static final String DEFAULT_HOST                    = "127.0.0.1";  
  •     private static final int    DEFAULT_PORT                    = 7777;  
  •   
  •     private static final String CLIENT_KEY_STORE_PASSWORD       = "123456";  
  •     private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";  
  •   
  •     private SSLSocket           sslSocket;  
  •   
  •     /** 
  •      * 启动客户端程序 
  •      *  
  •      * @param args 
  •      */  
  •     public static void main(String[] args) {  
  •        Client client = new Client();  
  •         client.init();  
  •         client.process();  
  •     }  
  •   
  •    
  •     public void process() {  
  •         if (sslSocket == null) {  
  •             System.out.println("ERROR");  
  •             return;  
  •         }  
  •         try {  
  •             InputStream input = sslSocket.getInputStream();  
  •             OutputStream output = sslSocket.getOutputStream();  
  •   
  •             BufferedInputStream bis = new BufferedInputStream(input);  
  •             BufferedOutputStream bos = new BufferedOutputStream(output);  
  •   
  •             bos.write("1234567890".getBytes());  
  •             bos.flush();  
  •   
  •             byte[] buffer = new byte[20];  
  •             bis.read(buffer);  
  •             System.out.println(new String(buffer));  
  •   
  •             sslSocket.close();  
  •         } catch (IOException e) {  
  •             System.out.println(e);  
  •         }  
  •     }  
  •   
  •   
  •     public void init() {  
  •         try {  
  •             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("src/ssl/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());  
  •             tks.load(new FileInputStream("src/ssl/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());  
  •   
  •             kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());  
  •             tmf.init(tks);  
  •   
  •             ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);  
  •   
  •             sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);  
  •         } catch (Exception e) {  
  •             System.out.println(e);  
  •         }  
  •     }  
  •   
  • }  
  •  

    启动Server

     

    启动Client,发送信息。

     

    Server接收如下:正确解密

     

     

     

    返回Client信息,如下:

     

     

     

     

    如此,就完成了服务端和客户端之间的基于身份认证的交互。

    client采用kclient.keystore中的clientkey私钥进行数据加密,发送给server。
    server采用tserver.keystore中的client.crt证书(包含了clientkey的公钥)对数据解密,如果解密成功,证明消息来自client,进行逻辑处理。

    server采用kserver.keystore中的serverkey私钥进行数据加密,发送给client。
    client采用tclient.keystore中的server.crt证书(包含了serverkey的公钥)对数据解密,如果解密成功,证明消息来自server,进行逻辑处理。

    如果过程中,解密失败,那么证明消息来源错误。不进行逻辑处理。这样就完成了双向的身份认证。

     


    总结

    以上是生活随笔为你收集整理的java实现 SSL双向认证的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。