文档章节

Java使用SSLSocket通信

摆渡者
 摆渡者
发布于 2016/04/01 20:14
字数 831
阅读 4532
收藏 88

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

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

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

openssl pkcs12 -export -clcerts -name www.mydomain.com \
-inkey private/client-key.pem -in certs/client.cer -out certs/client.keystore

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

openssl pkcs12 -export -clcerts -name www.mydomain.com \
-inkey private/server-key.pem -in certs/server.cer -out certs/server.keystore

受信任的CA证书的导出:

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通信客户端:

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通信服务器端:

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();
		}
	}
}

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

客户端执行结果:

© 著作权归作者所有

摆渡者
粉丝 345
博文 171
码字总数 206504
作品 0
成都
程序员
私信 提问
加载中

评论(1)

2006
2006
很赞
用SSL构建安全的Socket

SSL(安全套接层)是 Netscape公司在1994年开发的,最初用于WEB浏览器,为浏览器与服务器间的数据传递提供安全保障,提供了加密、来源认证和数据完整性的功能。现在SSL3.0得到了普遍的使用,它...

天空风
2012/05/16
252
0
server端如何控制agent 的行为通信,求教!!!

java中普通的serversocket可以监听sslsocket的连接请求么? 就是说我在客户端用java普通的serversocket accept()可以监听来自服务端ssl连接么,以达到服务端发送命令控制客户端的目的???...

hellojjkk
2012/06/09
456
0
android httpClient(https/http)的优化构建方式一

参考:基于java的https双向认证,android上亦可用 Android Https相关完全解析 当OkHttp遇到Https 在android中,经常不可避免的的使用https和http访问网络数据,因此需要先构建一个网络访问cli...

IamOkay
2014/10/31
3.1K
0
android中关于读取pem文件建立SSL连接的问题

最近在做的项目用到SSL协议,需要读取pem 文件建立SSL连接,用的是 socket连接方式。连的是银联的一个端口。但是一直没响应,我不知道是不是我代码哪里写错了(SSl这块我原本也不懂,在网上找...

zhanglibin123488
2015/11/10
2.2K
1
HTTPS的证书未经权威机构认证的情况下,访问HTTPS站点的两种方法

注意一下文章中提到的jsse在jdk1.4以后已经集成了,不必纠结. 摘 要 JSSE是一个SSL和TLS的纯Java实现,通过JSSE可以很容易地编程实现对HTTPS站点的访问。但是,如果该站点的证书未经权威机构的...

swearyd457
2015/08/18
349
0

没有更多内容

加载失败,请刷新页面

加载更多

golang-字符串-地址分析

demo package mainimport "fmt"func main() {str := "map.baidu.com"fmt.Println(&str, str)str = str[0:5]fmt.Println(&str, str)str = "abc"fmt.Println(&s......

李琼涛
今天
4
0
Spring Boot WebFlux 增删改查完整实战 demo

03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello 。这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD WebFlux 应用,让开发更方便。这里...

泥瓦匠BYSocket
今天
6
0
从0开始学FreeRTOS-(列表与列表项)-3

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
今天
4
0
Java反射

Java 反射 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的 Class,Class 类 用于表示.class 文件(字节码)) 一、反射的概述 定义:JAVA 反射机制是在运行状态中,对于任...

zzz1122334
今天
5
0
聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部