Netty SSL双向验证
一· 快速命令
1.生成ca证书
openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500
在本目录得到 ca.key 和 ca.crt 文件
2.生成服务端和客户端私钥
openssl genrsa -des3 -out server.key 1024
openssl genrsa -des3 -out client.key 1024
3.根据 key 生成 csr 文件
openssl req -new -key server.key -out server.csr
openssl req -new -key client.key -out client.csr
4.根据 ca 证书 server.csr 和 client.csr 生成 x509 证书
openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
openssl x509 -req -days 36500 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
5.将 key 文件进行 PKCS#8 编码
openssl pkcs8 -topk8 -in server.key -out pkcs8_server.key -nocrypt
openssl pkcs8 -topk8 -in client.key -out pkcs8_client.key -nocrypt
最后得到有用的文件分别为
- 服务器端: ca.crt、server.crt、pkcs8_server.key
- 客户端端: ca.crt、client.crt、pkcs8_client.key
6. 查看命令
openssl 查看证书细节
打印证书的过期时间
openssl x509 -in signed.crt -noout -dates
打印出证书的内容:
openssl x509 -in cert.pem -noout -text
打印出证书的系列号
openssl x509 -in cert.pem -noout -serial
打印出证书的拥有者名字
openssl x509 -in cert.pem -noout -subject
以RFC2253规定的格式打印出证书的拥有者名字
openssl x509 -in cert.pem -noout -subject -nameopt RFC2253
在支持UTF8的终端一行过打印出证书的拥有者名字
openssl x509 -in cert.pem -noout -subject -nameopt oneline -nameopt -escmsb
打印出证书的MD5特征参数
openssl x509 -in cert.pem -noout -fingerprint
打印出证书的SHA特征参数
openssl x509 -sha1 -in cert.pem -noout -fingerprint
把PEM格式的证书转化成DER格式
openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
把一个证书转化成CSR
openssl x509 -x509toreq -in cert.pem -out req.pem -signkey key.pem
给一个CSR进行处理,颁发字签名证书,增加CA扩展项
openssl x509 -req -in careq.pem -extfile openssl.cnf -extensions v3_ca -signkey key.pem -out cacert.pem
给一个CSR签名,增加用户证书扩展项
openssl x509 -req -in req.pem -extfile openssl.cnf -extensions v3_usr -CA cacert.pem -CAkey key.pem -CAcreateserial
查看csr文件细节:
openssl req -in my.csr -noout -text
二· 部分参考代码
服务端的代码:
@Slf4j
public class HidsSslContextBuilder {
private final static String serverCrt = "/static/keys/server.crt";
private final static String serverKey = "/static/keys/pkcs8_server.key";
private final static String caCrt = "/static/keys/ca.crt";
private final static String keyPassword = "";
public static SslContext build(ClientAuth clientAuth) {
InputStream certInput = null;
InputStream priKeyInput = null;
InputStream caInput = null;
try {
certInput = HidsSslContextBuilder.class.getResourceAsStream(serverCrt);
priKeyInput = HidsSslContextBuilder.class.getResourceAsStream(serverKey);
caInput = HidsSslContextBuilder.class.getResourceAsStream(caCrt);
return SslContextBuilder.forServer(certInput, priKeyInput)
.clientAuth(clientAuth)
.trustManager(caInput).build();
} catch (Throwable e) {
log.error("HidsSslContextBuilder", e);
} finally {
IOUtils.closeQuietly(certInput);
IOUtils.closeQuietly(priKeyInput);
IOUtils.closeQuietly(caInput);
}
return null;
}
public static SslContext buildSelfSignedCer() {
try {
SelfSignedCertificate ssc = new SelfSignedCertificate();
return SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
.build();
} catch (Throwable e) {
log.error("buildSelfSignedCer", e);
}
return null;
}
}
...
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
// INBOUND: from head to tail
// OUTBOUND: from tail to head
// ssl
if (sslContext != null) {
pipeline.addLast(sslContext.newHandler(socketChannel.alloc()));
}
pipeline.addLast("TLVDecoder", new TLVDecoder());
pipeline.addLast("TLVEncoder", new TLVEncoder());
pipeline.addLast("Decompressor", new Decompressor());
pipeline.addLast("Compressor", new Compressor());
pipeline.addLast("tlvChannelHandler", tlvChannelHandler);
// 增加channel对应的数据
prepareChannelContext(socketChannel);
}
客户端的测试代码
public class ClientChannelTest {
@Test
public void testClient() throws Throwable {
String host = "0.0.0.0";
int port = 8888;
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
final SslContext sslCtx = SslContextBuilder.forClient()
// 双向验证
// .keyManager(this.getClass().getResourceAsStream("/keys/client.crt"),
// this.getClass().getResourceAsStream("/keys/pkcs8_client.key"))
// CA证书,验证对方证书
.trustManager(this.getClass().getResourceAsStream("/keys/ca.crt"))
// 不验证SERVER
// .trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
Bootstrap b = new Bootstrap(); // (1)
b.group(workerGroup); // (2)
b.channel(NioSocketChannel.class); // (3)
b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
ch.pipeline().addLast(new TLVDecoder());
ch.pipeline().addLast(new TLVEncoder());
ch.pipeline().addLast("Decompressor", new Decompressor());
ch.pipeline().addLast("Compressor", new Compressor());
ch.pipeline().addLast(new ClientHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync(); // (5)
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
}
在Channel上绑定链接上下文信息,类似Session的功能,存储在Channel中的Attr中。
public class ChannelUtils {
public static ClientContext getOrCreate(Channel socketChannel) {
AttributeKey<ClientContext> key = AttributeKey.valueOf(ClientContext.class.toString());
Attribute<ClientContext> attr = socketChannel.attr(key);
if (attr.get() == null) {
attr.set(createClientContext(socketChannel));
}
return attr.get();
}
private static ClientContext createClientContext(Channel socketChannel) {
return new DefaultClientContext(socketChannel.pipeline());
}
}
三· 参考
- Netty实现SSL双向验证完整实例
- openssl req(生成证书请求和自建CA)
- 如何创建私有 CA 并签发证书
- keytool制作CA根证书以及颁发二级证书
- SSL-用Keytool和OpenSSL生成和签发数字证书
- netty实现SSL 双向认证与用jmeter测试
Netty SSL双向验证的更多相关文章
- Netty实现SSL双向验证完整实例
Netty实现SSL双向验证完整实例 博客分类: netty nettyssl自签证书 一.证书准备 要使用ssl双向验证,就必须先要生成服务端和客户端的证书,并相互添加信任,具体流程如下(本人调试 ...
- 请给你的短信验证码接口加上SSL双向验证
序言 去年年底闲来几天,有位同事专门在网上找一些注册型的app和网站,研究其短信接口是否安全,半天下来找到30来家,一些短信接口由于分析难度原因,没有继续深入,但差不多挖掘到20来个,可以肆意被调用, ...
- nginx配置ssl双向验证 nginx https ssl证书配置
1.安装nginx 参考<nginx安装>:http://www.ttlsa.com/nginx/nginx-install-on-linux/ 如果你想在单IP/服务器上配置多个http ...
- MQTT研究之EMQ:【SSL双向验证】
EMQ是当前MQTT中,用于物联网领域中比较出色的一个broker,今天我这里要记录和分享的是关于SSL安全通信的配置和注意细节. 环境: 1. 单台Linux CentOS7.2系统,安装一个EMQ ...
- MQTT研究之EMQ:【SSL证书链验证】
1. 创建证书链(shell脚本) 客户端证书链关系: rootCA-->chainca1-->chainca2-->chainca3 ca caCert1 caCert2 caCe ...
- Netty SSL安全配置
Netty SSL安全配置 [TOC] 摘要 在研发蜂鸟部署平台的过程中,涉及到平台网关和前置agent的通信加密,虽然目前软件在内网中,但是由于蜂鸟平台和agent的特殊性,一旦被控制,部署的软件就 ...
- 使用HttpClient连接池进行https单双向验证
https单双向验证环境的搭建参见:http://www.cnblogs.com/YDDMAX/p/5368404.html 一.单向握手 示例程序: package com.ydd.study.he ...
- SSL双向认证java实现(转)
本文通过模拟场景,介绍SSL双向认证的java实现 默认的情况下,我认为读者已经对SSL原理有一定的了解,所以文章中对SSL的原理,不做详细的介绍. 如果有这个需要,那么通过GOOGLE,可以搜索到很 ...
- linux:Nginx+https双向验证(数字安全证书)
本文由邓亚运提供 Nginx+https双向验证 说明: 要想实现nginx的https,nginx必须启用http_ssl模块:在编译时加上--with-http_ssl_module参数就ok.另 ...
- SSL双向认证(高清版)
介绍了SSL双向认证的一些基本问题,以及使用Nginx+PHP基于它搭建https的Webservice. 之前的方式只是实现1:1的模式,昨天同事继续实现了n:1的模式,这里我再整理记录下. 由于n ...
随机推荐
- Diffusion系列 - DDPM 公式推导 + 代码 -(二)
Denoising Diffusion Probabilistic Model(DDPM)原理 1. 生成模型对比 记 真实图片为 \(x_0\),噪声图片为 \(x_t\),噪声变量 \(z\sim ...
- 墨天轮沙龙 | Proxima 刘方:阿里巴巴大规模向量检索实时服务化引擎 Proxima SE
导读 随着 AI 技术的广泛应用,以及数据规模的不断增长,向量检索也逐渐成了 AI 技术链路中不可或缺的一环. 在11月16日举办的[墨天轮数据库沙龙-向量数据库专场]邀请到阿里巴巴高级技术专家刘方, ...
- springboot admin 整合nacos,context-path问题
1.在使用springboot admin 整合nacos时发现问题,springboot admin server访问admin client的默认地址为http://ip:port/actuato ...
- 一文读懂 Prometheus 长期存储主流方案
嘉宾 | 霍秉杰 整理 | 西京刀客 出品 | CSDN 云原生 Prometheus 作为云原生时代崛起的标志性项目,已经成为可观测领域的事实标准.Prometheus 是单实例不可扩展的,那么如果 ...
- direasch目录扫描
direasch目录扫描工具 安装: 1.github源码下载解压 使用 git 安装:(推荐git clone https://github.com/maurosoria/dirsearch.git ...
- mysql重置id排列重新排序
1.删除表中的原有的主键字段 ALTER TABLE table2 DROP id 2.表中重新创建一个字段 ALTER TABLE table2 ADD id int NOT NULL FIRST; ...
- spring boot下跨域安全配置
1 @Bean 2 public FilterRegistrationBean corsFilter() { 3 final UrlBasedCorsConfigurationSource sourc ...
- Next.js 零基础开发入门教程2 构建基础脚手架 2024最新更新中|曲速引擎 Warp Drive
开发目标 我们将构建一个简化版本的财务仪表板,其内容包括:公共主页.登录页面.受身份验证保护的仪表板页面.用户可以添加.编辑和删除发票 这篇文章先创建一个简单的nextjs脚手架页面 安装pnpm包管 ...
- Java面试真题之中级进阶(线程,进程,序列化,IO流,NIO)
前言 本来想着给自己放松一下,刷刷博客,慕然回首,线程.程序.进程?Java 序列化?Java 中 IO 流? Java IO与 NIO的区别(补充)?似乎有点模糊了,那就大概看一下Java基础面试题 ...
- 0.4 Nomenclature and notation