【Netty源码解读和权威指南】第38篇:Netty SSL TLS安全传输——HTTPS背后的Netty实现
·
上一篇【第37篇】Netty流量整形——优雅控制客户端发送速率
下一篇【第39篇】Netty内存泄漏检测机制源码解析——守护ByteBuf的"生死账本"
一、TLS握手流程
客户端 服务端
|------ClientHello----------->| (支持的加密套件)
|<-----ServerHello------------| (选定加密套件+证书)
|<-----Certificate-----------| (服务端证书)
|<-----ServerHelloDone-------| (握手完成)
|------ClientKeyExchange----->| (加密的预主密钥)
|------ChangeCipherSpec------>| (切换加密模式)
|------Finished-------------->|
|<-----ChangeCipherSpec-------|
|<-----Finished---------------|
| |
|<====加密通信开始==============>|
二、SslContext配置
// 服务端SSL配置
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContext sslCtx = SslContextBuilder
.forServer(cert.certificate(), cert.privateKey())
.sslProvider(SslProvider.OPENSSL) // 优先使用OpenSSL
.build();
// 客户端SSL配置
SslContext clientCtx = SslContextBuilder
.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE) // 仅测试用
.build();
三、SslHandler集成
// 服务端Pipeline
pipeline.addLast(sslCtx.newHandler(ch.alloc())); // SSL加解密
pipeline.addLast(new HttpServerCodec()); // HTTP编解码
pipeline.addLast(new HttpServerHandler()); // 业务逻辑
// 客户端Pipeline
pipeline.addLast(clientCtx.newHandler(ch.alloc(), host, port));
pipeline.addLast(new HttpClientCodec());
pipeline.addLast(new HttpClientHandler());
四、OpenSSL vs JDK SSL
| 对比 | JDK SSL | OpenSSL |
|---|---|---|
| 性能 | 基准 | 快2-3倍 |
| 内存 | 堆内 | 堆外(更少GC) |
| 依赖 | 无 | 需安装OpenSSL |
| 支持 | 全平台 | Linux最佳 |
启用OpenSSL:
// pom.xml
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
</dependency>
// 代码配置
.sslProvider(SslProvider.OPENSSL)
五、完整HTTPS服务器
public class HttpsServer {
public static void main(String[] args) throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate();
SslContext sslCtx = SslContextBuilder
.forServer(cert.certificate(), cert.privateKey()).build();
EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup();
try {
new ServerBootstrap().group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel ch) {
ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new HttpServerExpectContinueHandler());
ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) {
String body = "Hello HTTPS!";
FullHttpResponse resp = new DefaultFullHttpResponse(
HTTP_1_1, OK, ctx.alloc().buffer().writeBytes(body.getBytes()));
resp.headers().set(CONTENT_LENGTH, body.length());
resp.headers().set(CONTENT_TYPE, "text/plain");
ctx.writeAndFlush(resp);
}
});
}
}).bind(8443).sync().channel().closeFuture().sync();
} finally { boss.shutdownGracefully(); worker.shutdownGracefully(); }
}
}
六、总结
| 步骤 | 配置 |
|---|---|
| 证书 | SelfSignedCertificate(测试) / CA证书(生产) |
| SslContext | SslContextBuilder配置Provider和证书 |
| 集成 | SslHandler添加到Pipeline首位 |
| 性能建议 | 生产环境使用OpenSSL Provider |
上一篇【第37篇】Netty流量整形——优雅控制客户端发送速率
下一篇【第39篇】Netty内存泄漏检测机制源码解析——守护ByteBuf的"生死账本"
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)