博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java使用SSLSocket通信
阅读量:5925 次
发布时间:2019-06-19

本文共 5595 字,大约阅读时间需要 18 分钟。

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

首先,需要将一文中生成的客户端及服务端私钥和数字证书进行导出,生成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();
        
}
    
}
}

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

客户端执行结果:

转载地址:http://tmovx.baihongyu.com/

你可能感兴趣的文章
iPhone比小米贵3000,贵在哪里?
查看>>
十年老站吐血迁移实录
查看>>
HTTP头信息
查看>>
负载均衡环境搭建实战之nginx和tomcat
查看>>
aws-ec2-双网卡问题
查看>>
装饰一个类及内部方法
查看>>
实施Exchange 2013中的 MailTip
查看>>
Windows Server 2016-图形化迁移FSMO角色
查看>>
京东订单自动评价方法
查看>>
Linux下JDK安装
查看>>
Bitcoin比特币与BlockChain区块链技术
查看>>
从0到1简易区块链开发手册V0.3-数据持久化与创世区块
查看>>
12C RAC for ASM添加磁盘步骤
查看>>
归档日志 delete input 和delete all input 区别
查看>>
最难面试IT公司的测试题
查看>>
Windows获取CPU、内存和磁盘使用率脚本
查看>>
Linux优化之IO子系统监控与调优
查看>>
Upgrade Oracle GI 11.2.0.4_to_12.1.0.2
查看>>
使用ansible 批量分发SSH Key
查看>>
安装MHA中清理Relay log报错
查看>>