Java下SSL的使用

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

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

Client:

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

启动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、付费专栏及课程。

余额充值