java ssl 双向认证

 

实现技术:
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代码

  1. public class Server implements Runnable{   
  2.   
  3.     private static final int     DEFAULT_PORT                     = 7777;   
  4.   
  5.     private static final String SERVER_KEY_STORE_PASSWORD        = "123456";   
  6.     private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";   
  7.   
  8.     private SSLServerSocket      serverSocket;   
  9.   
  10.     /**
  11.       * 启动程序
  12.       *
  13.       * @param args
  14.       */  
  15.     public static void main(String[] args) {   
  16.          Server server = new Server();   
  17.          server.init();   
  18.          Thread thread = new Thread(server);   
  19.          thread.start();   
  20.      }   
  21.   
  22.     public synchronized void start() {   
  23.         if (serverSocket == null) {   
  24.              System.out.println("ERROR");   
  25.             return;   
  26.          }   
  27.         while (true) {   
  28.             try {   
  29.                  Socket s = serverSocket.accept();   
  30.                  InputStream input = s.getInputStream();   
  31.                  OutputStream output = s.getOutputStream();   
  32.   
  33.                  BufferedInputStream bis = new BufferedInputStream(input);   
  34.                  BufferedOutputStream bos = new BufferedOutputStream(output);   
  35.   
  36.                 byte[] buffer = new byte[20];   
  37.                  bis.read(buffer);   
  38.                  System.out.println("------receive:--------"+new String(buffer).toString());   
  39.   
  40.                  bos.write("yes".getBytes());   
  41.                  bos.flush();   
  42.   
  43.                  s.close();   
  44.              } catch (Exception e) {   
  45.                  System.out.println(e);   
  46.              }   
  47.          }   
  48.      }   
  49.     public void init() {   
  50.         try {   
  51.              SSLContext ctx = SSLContext.getInstance("SSL");   
  52.   
  53.              KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");   
  54.              TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");   
  55.   
  56.              KeyStore ks = KeyStore.getInstance("JKS");   
  57.              KeyStore tks = KeyStore.getInstance("JKS");   
  58.   
  59.              ks.load(new FileInputStream("src/ssl/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());   
  60.              tks.load(new FileInputStream("src/ssl/tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());   
  61.   
  62.              kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());   
  63.              tmf.init(tks);   
  64.   
  65.              ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);   
  66.   
  67.              serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);   
  68.              serverSocket.setNeedClientAuth(true);   
  69.          } catch (Exception e) {   
  70.              System.out.println(e);   
  71.          }   
  72.      }   
  73.   
  74.     public void run() {   
  75.         // TODO Auto-generated method stub   
  76.          start();   
  77.      }   
  78. }  

 

Client:

Java代码
  1. package ssl;   
  2.   
  3. import java.io.BufferedInputStream;   
  4. import java.io.BufferedOutputStream;   
  5. import java.io.FileInputStream;   
  6. import java.io.IOException;   
  7. import java.io.InputStream;   
  8. import java.io.OutputStream;   
  9. import java.security.KeyStore;   
  10.   
  11. import javax.net.ssl.KeyManagerFactory;   
  12. import javax.net.ssl.SSLContext;   
  13. import javax.net.ssl.SSLSocket;   
  14. import javax.net.ssl.TrustManagerFactory;   
  15.   
  16. /**
  17. * SSL Client
  18. *
  19. * @author Leo
  20. */  
  21. public class Client {   
  22.   
  23.     private static final String DEFAULT_HOST                     = "127.0.0.1";   
  24.     private static final int     DEFAULT_PORT                     = 7777;   
  25.   
  26.     private static final String CLIENT_KEY_STORE_PASSWORD        = "123456";   
  27.     private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";   
  28.   
  29.     private SSLSocket            sslSocket;   
  30.   
  31.     /**
  32.       * 启动客户端程序
  33.       *
  34.       * @param args
  35.       */  
  36.     public static void main(String[] args) {   
  37.         Client client = new Client();   
  38.          client.init();   
  39.          client.process();   
  40.      }   
  41.   
  42.   
  43.     public void process() {   
  44.         if (sslSocket == null) {   
  45.              System.out.println("ERROR");   
  46.             return;   
  47.          }   
  48.         try {   
  49.              InputStream input = sslSocket.getInputStream();   
  50.              OutputStream output = sslSocket.getOutputStream();   
  51.   
  52.              BufferedInputStream bis = new BufferedInputStream(input);   
  53.              BufferedOutputStream bos = new BufferedOutputStream(output);   
  54.   
  55.              bos.write("1234567890".getBytes());   
  56.              bos.flush();   
  57.   
  58.             byte[] buffer = new byte[20];   
  59.              bis.read(buffer);   
  60.              System.out.println(new String(buffer));   
  61.   
  62.              sslSocket.close();   
  63.          } catch (IOException e) {   
  64.              System.out.println(e);   
  65.          }   
  66.      }   
  67.   
  68.   
  69.     public void init() {   
  70.         try {   
  71.              SSLContext ctx = SSLContext.getInstance("SSL");   
  72.   
  73.              KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");   
  74.              TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");   
  75.   
  76.              KeyStore ks = KeyStore.getInstance("JKS");   
  77.              KeyStore tks = KeyStore.getInstance("JKS");   
  78.   
  79.              ks.load(new FileInputStream("src/ssl/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());   
  80.              tks.load(new FileInputStream("src/ssl/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());   
  81.   
  82.              kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());   
  83.              tmf.init(tks);   
  84.   
  85.              ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);   
  86.   
  87.              sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);   
  88.          } catch (Exception e) {   
  89.              System.out.println(e);   
  90.          }   
  91.      }   
  92.   
  93. }  

 

启动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,exception,server,ssl,解密,buffer)