Java SSLSocket
Java SSLSocket
JSSE(Java Security Socket Extension)是Sun公司为了解决互联网信息安全传输提出的一个解决方案,它实现了SSL和TSL协议,包含了数据加密、服务器验证、消息完整性和客户端验证等技术。通过使用JSSE简洁的API,可以在客户端和服务器端之间通过SSL/TSL协议安全地传输数据。
1、生成证书
需要将OpenSSL生成根证书CA及签发子证书一文中生成的客户端及服务端私钥和数字证书进行导出,生成Java环境可用的keystore文件。
(1)客户端私钥与证书的导出:
openssl pkcs12 -export -clcerts -name www.mydomain.com \
-inkey private/client-key.pem -in certs/client.cer -out certs/client.keystore

(2)服务器端私钥与证书的导出:
openssl pkcs12 -export -clcerts -name www.mydomain.com \
-inkey private/server-key.pem -in certs/server.cer -out certs/server.keystore

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

2、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上下文
SSLContext context = SSLContext.getInstance("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。
3、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上下文
SSLContext context = SSLContext.getInstance("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();
}
}
}
先运行服务器端,再运行客户端。服务器端执行结果:

客户端执行结果:

参考博客:
[1]Java使用SSLSocket通信
[2]Java实现SSL双向认证的方法
Java SSLSocket的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- java获取https网站证书,附带调用https:webservice接口
一.java 获取https网站证书: 1.创建一个java工程,新建InstallCert类,将以下代码复制进去 package com; import java.io.BufferedReader ...
- JAVA错误汇总
1.Slf4J-API版本兼容 问题描述 Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.hel ...
- 解决 java 使用ssl过程中出现"PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
今天,封装HttpClient使用ssl时报一下错误: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorExc ...
- java 实现https请求
java 实现https请求 JSSE是一个SSL和TLS的纯Java实现,通过JSSE可以很容易地编程实现对HTTPS站点的访问.但是,如果该站点的证书未经权威机构的验证,JSSE将拒绝信任该证书从 ...
- Java手动添加SSL证书
出现错误为 SSLHandshakeException - unable to find valid certification path to requested target 在服务器上找到对应的 ...
- java socket编程开发简单例子 与 nio非阻塞通道
基本socket编程 1.以下只是简单例子,没有用多线程处理,只能一发一收(由于scan.nextLine()线程会进入等待状态),使用时可以根据具体项目功能进行优化处理 2.以下代码使用了1.8新特 ...
- SSL双向认证java实现(转)
本文通过模拟场景,介绍SSL双向认证的java实现 默认的情况下,我认为读者已经对SSL原理有一定的了解,所以文章中对SSL的原理,不做详细的介绍. 如果有这个需要,那么通过GOOGLE,可以搜索到很 ...
- JAVA Socket 实现HTTP与HTTPS客户端发送POST与GET方式请求
JAVA Socket 实现HTTP与HTTPS客户端发送POST与GET方式请求 哇,一看标题怎么这么长啊,其实意思很简单,哥讨厌用HTTP Client做POST与GET提交 觉得那个毕竟是别人写 ...
随机推荐
- MySQL报错汇总[10/29更新]
- vue路由监听和参数监听
1.路由携带数据跳转 routerAction(hideDisplays, data) { switch (hideDisplays) { case "pubAccountMenu" ...
- echarts 让轴自适应数据为小数整数
echarts 让轴自适应数据为小数整数,以解决y轴数值重复的问题 工作中突然遇到这个问题 试了一下用formatter自适应 ok 在yAxis中提阿尼按键属性 axisLabel 1 axis ...
- 使用ssh连接到centos7中docker容器
任务: 使用ssh连接到centos7中docker容器 实验步骤: 实验环境搭建,详情请看上一篇. 因为docker中容器的ip通常来说是和真机以及centos7的ip不属于一个网段,因此直接访问是 ...
- 2020 ICPC 沈阳站 I - Rise of Shadows 题解
题面看这里 \(PS\):符号 \([\ \rm P\ ]\) 的意义是:当表达式 \(\rm P\) 为真则取值为 \(1\),为假则取值为 \(0\). 题目大意 给你一个一天有 \(H\) ...
- 【Python+postman接口自动化测试】(3)什么是接口测试?
什么是接口测试? 接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点.测试的重点是要检查数据的交换.传递和控制管理过程,以及系统间的相互逻辑依 ...
- Springboot 整合RabbitMq ,用心看完这一篇就够了
该篇文章内容较多,包括有rabbitMq相关的一些简单理论介绍,provider消息推送实例,consumer消息消费实例,Direct.Topic.Fanout的使用,消息回调.手动确认等. (但是 ...
- ES6基础知识(Reflect)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 菜鸡的Java笔记 类图
类图 1.如何实现类图的描述 2.时序图的使用 从实际i的开发标准:应该在项目编写钱设计类图 而现在的开发大部分情况下, ...
- python实现图像直方图
目录: (一)直方图的使用 正文: (一)直方图的使用 1 from matplotlib import pyplot as plt 2 def plot_demo(image): 3 print(i ...