Java使用SSLSocket通信

JSSE(Java Security Socket Extension)是Sun公司为了解决互联网信息安全传输提出的一个解决方案,它实现了SSL和TSL协议,包含了数据加密、服务器验证、消息完整性和客户端验证等技术。通过使用JSSE简洁的API,可以在客户端和服务器端之间通过SSL/TSL协议安全地传输数据。

首先,需要将OpenSSL生成根证书CA及签发子证书一文中生成的客户端及服务端私钥和数字证书进行导出,生成Java环境可用的keystore文件。

客户端私钥与证书的导出:

?


1

2

openssl pkcs12 -export -clcerts -name www.mydomain.com \

-inkey private/client-key.pem -in certs/client.cer -out certs/client.keystore

服务器端私钥与证书的导出:

?


1

2

openssl pkcs12 -export -clcerts -name www.mydomain.com \

-inkey private/server-key.pem -in certs/server.cer -out certs/server.keystore

受信任的CA证书的导出:

?


1

2

keytool -importcert -trustcacerts -alias www.mydomain.com -file certs/ca.cer \

-keystore certs/ca-trust.keystore

之后,便会在certs文件夹下生成ca-trust.keystore文件。加上上面生成的server.keystore和client.keystore,certs下会生成这三个文件:

Java实现的SSL通信客户端:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

package com.demo.ssl;

 

import java.io.FileInputStream;

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;

 

public class SSLClient {

    private SSLSocket sslSocket;

    public static void main(String[] args) throws Exception {

        SSLClient client = new SSLClient();

        client.init();

        System.out.println("SSLClient initialized.");

        client.process();

    }

     

    //客户端将要使用到client.keystore和ca-trust.keystore

    public void init() throws Exception {

        String host = "127.0.0.1";

        int port = 1234;

        String keystorePath = "/home/user/CA/certs/client.keystore";

        String trustKeystorePath = "/home/user/CA/certs/ca-trust.keystore";

        String keystorePassword = "abc123_";

        SSLContext context = SSLContext.getInstance("SSL");

        //客户端证书库

        KeyStore clientKeystore = KeyStore.getInstance("pkcs12");

        FileInputStream keystoreFis = new FileInputStream(keystorePath);

        clientKeystore.load(keystoreFis, keystorePassword.toCharArray());

        //信任证书库

        KeyStore trustKeystore = KeyStore.getInstance("jks");

        FileInputStream trustKeystoreFis = new FileInputStream(trustKeystorePath);

        trustKeystore.load(trustKeystoreFis, keystorePassword.toCharArray());

         

        //密钥库

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");

        kmf.init(clientKeystore, keystorePassword.toCharArray());

 

        //信任库

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");

        tmf.init(trustKeystore);

         

        //初始化SSL上下文

        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

         

        sslSocket = (SSLSocket)context.getSocketFactory().createSocket(host, port);

    }

     

    public void process() throws Exception {

        //往SSLSocket中写入数据

        String hello = "hello boy!";

        OutputStream out = sslSocket.getOutputStream();

        out.write(hello.getBytes(), 0, hello.getBytes().length);

        out.flush();

         

        //从SSLSocket中读取数据

        InputStream in = sslSocket.getInputStream();

        byte[] buffer = new byte[50];

        in.read(buffer);

        System.out.println(new String(buffer));

    }

}

初始化时,首先取得SSLContext、KeyManagerFactory、TrustManagerFactory实例,然后加载客户端的密钥库和信任库到相应的KeyStore,对KeyManagerFactory和TrustManagerFactory进行初始化,最后用KeyManagerFactory和TrustManagerFactory对SSLContext进行初始化,并创建SSLSocket。

Java实现的SSL通信服务器端:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

package com.demo.ssl;

 

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;

 

public class SSLServer {

    private SSLServerSocket sslServerSocket;

    public static void main(String[] args) throws Exception {

        SSLServer server = new SSLServer();

        server.init();

        System.out.println("SSLServer initialized.");

        server.process();

    }

     

    //服务器端将要使用到server.keystore和ca-trust.keystore

    public void init() throws Exception {

        int port = 1234;

        String keystorePath = "/home/user/CA/certs/server.keystore";

        String trustKeystorePath = "/home/user/CA/certs/ca-trust.keystore";

        String keystorePassword = "abc123_";

        SSLContext context = SSLContext.getInstance("SSL");

         

        //客户端证书库

        KeyStore keystore = KeyStore.getInstance("pkcs12");

        FileInputStream keystoreFis = new FileInputStream(keystorePath);

        keystore.load(keystoreFis, keystorePassword.toCharArray());

        //信任证书库

        KeyStore trustKeystore = KeyStore.getInstance("jks");

        FileInputStream trustKeystoreFis = new FileInputStream(trustKeystorePath);

        trustKeystore.load(trustKeystoreFis, keystorePassword.toCharArray());

         

        //密钥库

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");

        kmf.init(keystore, keystorePassword.toCharArray());

 

        //信任库

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");

        tmf.init(trustKeystore);

         

        //初始化SSL上下文

        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        //初始化SSLSocket

        sslServerSocket = (SSLServerSocket)context.getServerSocketFactory().createServerSocket(port);

        //设置这个SSLServerSocket需要授权的客户端访问

        sslServerSocket.setNeedClientAuth(true);

    }

     

    public void process() throws Exception {

        String bye = "Bye!";

        byte[] buffer = new byte[50];

        while(true) {

            Socket socket = sslServerSocket.accept();

            InputStream in = socket.getInputStream();

            in.read(buffer);

            System.out.println("Received: " new String(buffer));

            OutputStream out = socket.getOutputStream();

            out.write(bye.getBytes());

            out.flush();

        }

    }

}

先运行服务器端,再运行客户端。服务器端执行结果:

客户端执行结果:

时间: 2024-08-16 23:36:42

Java使用SSLSocket通信的相关文章

socket-cocos2d-x 客户端和java mina 服务器通信问题

问题描述 cocos2d-x 客户端和java mina 服务器通信问题 首先贴出我的客户端的代码 ODSocket cSocket; cSocket.Init(); cSocket.Create(AF_INET,SOCK_STREAM,0); cSocket.Connect("127.0.0.1",8120); char recvBuf[1204] = ""; Per per; per.len=8; per.code=789; per.playerid=12346

局域网-java socket 的通信问题? 求解释?

问题描述 java socket 的通信问题? 求解释? 客户端和服务端分别在两个局域网内怎么通过java socket 通信? 解决方案 http://www.oschina.net/question/1251494_161695?sort=time&p=1 解决方案二: 通过中转,或者路由做映射 解决方案三: 我建议你还是webservice 好些,简单好用 解决方案四: 我觉得你这个问题不是怎么通过socket去通信而是你怎么让这两个机子的网络联通就好比你再客户端ping服务器如果能pin

java与单片机通信问题

问题描述 java与单片机通信问题 我用java写了一个控制单片机的界面,想在电脑上通过点击这个界面上的控件,来控制单片机.比如:我点击"蜂鸣器",那么单片机上的蜂鸣器就叫. 现在的问题是:不能解决java怎么利用串口和单片机进行通信.求大虾指点指点.谢谢啦 解决方案 首先你必须得懂java怎么通过串口通信,否则一切都是白谈. 其次设计通信协议,比如上位机发送0x01,表示要蜂鸣器响一下:然后单片机通过串口中断获取到这个0x01. 之后单片机控制蜂鸣器响就行了. 解决方案二: java

java中socket通信问题,急急急

问题描述 java中socket通信问题,急急急 客户端和服务端用socket建立通信进行文件传输,客户端用outputstream将文件写入流中,在服务端用输入流读取.这时候客户端不想传了,断开连接并告知服务器.服务端如何获知客户端已经断开连接了. 解决方案 你客户端断开连接的时候进行了哪些操作?想想这些操作会对服务器端产生什么影响呗· 解决方案二: 服务端一直在循环监听是否有客户端连接,并不会知道某个客户端已经断开.建议客户端断开之前先执行某条协议,服务器收到这条协议便知道你要断开咯

java编程 即时通信 自动显示 与163邮箱相似

问题描述 java编程 即时通信 自动显示 与163邮箱相似 本人想实现一个功能:比如在OA系统中,上级给你下发一个任务,在你登陆这个系统的情况下,不用自己手动刷新,让他自己刷新,注意并没有打开当前页面! 解决方案 如何设置163邮箱邮件自动分类自动登录163邮箱的批处理LoadRunner 自动登录163邮箱

使用JAVA实现http通信详解_java

Http通信概述 Http通信主要有两种方式POST方式和GET方式.前者通过Http消息实体发送数据给服务器,安全性高,数据传输大小没有限制,后者通过URL的查询字符串传递给服务器参数,以明文显示在浏览器地址栏,保密性差,最多传输2048个字符.但是GET请求并不是一无是处--GET请求大多用于查询(读取资源),效率高.POST请求用于注册.登录等安全性较高且向数据库中写入数据的操作. 除了POST和GET,http通信还有其他方式!请参见http请求的方法 编码前的准备 在进行编码之前,我们

java线程间通信

线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 例如,线程B可以等待线程A的一个信号,这个信号会通知线程B数据已经准备好了.本文将讲解以下几个JAVA线程间通信的主题: 1.通过共享对象通信 2.忙等待 3.wait(),notify()和notifyAll() 4.丢失的信号 5.假唤醒 6.多线程等待相同信号 7.不要对常量字符串或全局对象调用wait() 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程A在一

求JAVA开发MQ通信资料

问题描述 谁有JAVA开发MQ通信的资料!最好是代码!救急啦! 解决方案 解决方案二:如果你有兴趣可以去看ApacheActiveMQ和Sun的OpenMQ的源码,并且他们都附有例子的.还有一点,去熟悉下JMS规范,因为这些不同的MQ产品都都完全遵循这个规范的.另外编程的话比较简单,一般我们也就只用到JMS规范里面提到的那些接口,具体的实现类一般由JNDI指定.配置稍稍复杂点,不过很值得学习.解决方案三:多谢指导!

使用Java实现串口通信_java

1.介绍 使用Java实现的串口通信程序,支持十六进制数据的发送与接收. 源码下载地址:http://download.csdn.net/detail/kong_gu_you_lan/9611343 效果图如下: 2.RXTXcomm Java串口通信依赖的jar包RXTXcomm.jar 下载地址:http://download.csdn.net/detail/kong_gu_you_lan/9611334 内含32位与64位版本 使用方法: 拷贝 RXTXcomm.jar 到 JAVA_HO