JAVA 双向SSL,SOCKET客户端/服务端

实现技术:
JSSE(Java Security Socket Extension)
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代码
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,进行逻辑处理。

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


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值