Java SSL Socket通讯示例

论坛 期权论坛 脚本     
匿名技术用户   2020-12-22 06:10   66   0

上一篇《OpenSSL与KeyStore指令小集》里面说到,最近研究SSL加密,会给出一个Java的小示例。复制一份可以运行的代码到生产上是非常不负责任的行为,不过小示例可以带我们入门,快速看清事物的本质。罗马不是一天建成的。

本文将给出一个Java SSL Socket的小例子,包括了Server和Client。希望大家上手之后,要多去研究相关的资料,理解基础概念。Java的优点是封装得比较彻底,需要介入的地方比较少,缺点是随着Java版本的升级和发展,会有很多新的概念和类涌出来,都要搞清楚要费不少力,另外代码量也比较大(生产级别的代码)。

具体代码

从最简单来说,Java里面只需要配置几个系统属性,创建及调用几个SSL相关的对象即可。这四个属性分别是:

  • javax.net.ssl.keyStore
    本方的密码,证书等存放地点(KeyStore文件地址)。
  • javax.net.ssl.keyStorePassword
    KeyStore的密码。没有密码可以不填。
  • javax.net.ssl.trustStore
    受信任证书的存放地点(TrustKeyStore文件地址)。
  • javax.net.ssl.trustStorePassword
    TrustKeyStore的密码。没有密码可以不填。

KeyStore类型默认是JKS类型的,不是的话,还需要设置 javax.net.ssl.keyStoreType和javax.net.ssl.trustStoreType。

Server端代码

每一次收新的连接,都新开一个线程接待。生产上请用线程池等技术。更推荐用Netty或Mina等框架处理。

  1. public class SslServer {
  2. public static void main(String[] args) throws Exception {
  3. System.setProperty("javax.net.debug", "ssl,handshake");
  4. System.setProperty("javax.net.ssl.keyStore", "./cfg/server.jks");
  5. System.setProperty("javax.net.ssl.keyStorePassword", "123456");
  6. System.setProperty("javax.net.ssl.trustStore", "./cfg/clienttrust.jks");
  7. System.setProperty("javax.net.ssl.trustStorePassword", "123456");
  8. SSLServerSocketFactory serverSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory
  9. .getDefault();
  10. SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory
  11. .createServerSocket(9100);
  12. // 要求客户端身份验证
  13. serverSocket.setNeedClientAuth(true);
  14. while (true) {
  15. SSLSocket socket = (SSLSocket) serverSocket.accept();
  16. Accepter accepter = new Accepter(socket);
  17. accepter.service();
  18. }
  19. }
  20. static class Accepter implements Runnable {
  21. private SSLSocket socket;
  22. public Accepter(SSLSocket socket) {
  23. this.socket = socket;
  24. }
  25. public void service() {
  26. Thread thread = new Thread(this);
  27. thread.start();
  28. }
  29. @Override
  30. public void run() {
  31. try {
  32. InputStream inputStream = socket.getInputStream();
  33. InputStreamReader inputstreamreader = new InputStreamReader(
  34. inputStream);
  35. BufferedReader bufferedreader = new BufferedReader(
  36. inputstreamreader);
  37. String string = null;
  38. while ((string = bufferedreader.readLine()) != null) {
  39. System.out.println(string);
  40. System.out.flush();
  41. }
  42. } catch (Exception e) {
  43. // replace with other code
  44. e.printStackTrace();
  45. }
  46. }
  47. }
  48. }
public class SslServer {
  public static void main(String[] args) throws Exception {
   System.setProperty("javax.net.debug", "ssl,handshake");

   System.setProperty("javax.net.ssl.keyStore", "./cfg/server.jks");
   System.setProperty("javax.net.ssl.keyStorePassword", "123456");
   System.setProperty("javax.net.ssl.trustStore", "./cfg/clienttrust.jks");
   System.setProperty("javax.net.ssl.trustStorePassword", "123456");

   SSLServerSocketFactory serverSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory
     .getDefault();
   SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory
     .createServerSocket(9100);
   // 要求客户端身份验证
   serverSocket.setNeedClientAuth(true);

   while (true) {
    SSLSocket socket = (SSLSocket) serverSocket.accept();
    Accepter accepter = new Accepter(socket);
    accepter.service();
   }
  }

  static class Accepter implements Runnable {
   private SSLSocket socket;

   public Accepter(SSLSocket socket) {
    this.socket = socket;
   }

   public void service() {
    Thread thread = new Thread(this);
    thread.start();
   }

   @Override
   public void run() {
    try {
     InputStream inputStream = socket.getInputStream();

     InputStreamReader inputstreamreader = new InputStreamReader(
       inputStream);
     BufferedReader bufferedreader = new BufferedReader(
       inputstreamreader);

     String string = null;
     while ((string = bufferedreader.readLine()) != null) {
      System.out.println(string);
      System.out.flush();
     }
    } catch (Exception e) {
     // replace with other code
     e.printStackTrace();
    }
   }
  }
 }

Client代码

建立连接,并发一个消息给Server。很简单。记得换行符以及调用flush方法。

  1. public class SslClient {
  2. public static void main(String[] args) throws Exception {
  3. System.setProperty("javax.net.debug", "ssl,handshake");
  4. System.setProperty("javax.net.ssl.keyStore", "./cfg/client.jks");
  5. System.setProperty("javax.net.ssl.keyStorePassword", "123456");
  6. System.setProperty("javax.net.ssl.trustStore", "./cfg/servertrust.jks");
  7. System.setProperty("javax.net.ssl.trustStorePassword", "123456");
  8. SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
  9. .getDefault();
  10. SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
  11. "127.0.0.1", 9100);
  12. OutputStream outputStream = sslsocket.getOutputStream();
  13. BufferedWriter bufferedWriter = new BufferedWriter(
  14. new OutputStreamWriter(outputStream));
  15. bufferedWriter.write("沉睡的雄狮\n");
  16. bufferedWriter.flush();
  17. TimeUnit.SECONDS.sleep(2000);
  18. }
  19. }
public class SslClient {
  public static void main(String[] args) throws Exception {
   System.setProperty("javax.net.debug", "ssl,handshake");

   System.setProperty("javax.net.ssl.keyStore", "./cfg/client.jks");
   System.setProperty("javax.net.ssl.keyStorePassword", "123456");
   System.setProperty("javax.net.ssl.trustStore", "./cfg/servertrust.jks");
   System.setProperty("javax.net.ssl.trustStorePassword", "123456");

   SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
     .getDefault();
   SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
     "127.0.0.1", 9100);

   OutputStream outputStream = sslsocket.getOutputStream();
   BufferedWriter bufferedWriter = new BufferedWriter(
     new OutputStreamWriter(outputStream));
   bufferedWriter.write("沉睡的雄狮\n");
   bufferedWriter.flush();

   TimeUnit.SECONDS.sleep(2000);
  }
 }

结束语

JDK后来加了SSLEngine这个类,具有异步通讯的能力。不过看官方文档,给出的代码很长。还是那句话,有条件的推荐用Netty或者Mina来处理通讯的问题,应该会比自己写的性能好一些。

Java官方SSL Socket文档



原文地址:http://blog.csdn.net/kimylrong/article/details/43603815


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP