Netty SSL双向验证

netty实现TLS/SSL双向加密认证 1、双向加密认证首先要获取到证书,可以先自己生成证书用于测试(实际获取到的公网证书使用方式其实差不多) (1)可以通过openssl生成证书 (2)首先要生成一份CA根证书,再由该证书生成服务器和客户端的证书 (3)完成基本的SSL/TLS服务器和客户端的双向加密通讯,一共需要生成5份证书 ①CA证书 ②服务器证书 ③服务器密钥 ④客户端证书 ⑤客户端密钥 (4)、一般证书有多种格式,这里我们用pem格式做示例(linux系统常用) 2、假设... 阅读详情

1. 环境说明

  • 本例使用windows10 + Win64OpenSSL-3_3_0(完整版,不是lite),netty版本4.1.77.Final,JDK-17
  • openssl官方推荐合作下载地址:https://slproweb.com/download/Win64OpenSSL-3_3_0.exe
  • ${openssl_home}是openssl的安装目录
  • 所有命令在${openssl_home}/bin目录下执行
  • windows下openssl的配置文件是${openssl_home}/bin/openssl.cfg,linux下是${openssl_home}/bin/openssl.conf,注意替换后缀名
  • 需要手动按照openssl.cfg的配置创建好各种目录、文件

2. 生成证书

2.1. 创建根证书 密钥+证书

openssl genrsa -des3 -out demoCA/private/ca.key 4096

openssl req -new -x509 -days 3650 -key demoCA/private/ca.key -out demoCA/certs/ca.crt

2.2. 生成请求证书密钥

openssl genrsa -des3 -out demoCA/private/server.key 2048

openssl genrsa -des3 -out demoCA/private/client.key 2048

2.3. 生成csr请求证书

openssl req -new -key demoCA/private/server.key -out demoCA/certs/server.csr -config openssl.cfg

openssl req -new -key demoCA/private/client.key -out demoCA/certs/client.csr -config openssl.cfg

2.4. ca证书对server.csr、client.csr签发生成x509证书

openssl x509 -req -days 3650 -in demoCA/certs/server.csr -CA demoCA/certs/ca.crt -CAkey demoCA/private/ca.key -CAcreateserial -out demoCA/certs/server.crt

openssl x509 -req -days 3650 -in demoCA/certs/client.csr -CA demoCA/certs/ca.crt -CAkey demoCA/private/ca.key -CAcreateserial -out demoCA/certs/client.crt

2.5. 请求证书PKCS#8编码

openssl pkcs8 -topk8 -in demoCA/private/server.key -out demoCA/private/pkcs8_server.key -nocrypt

openssl pkcs8 -topk8 -in demoCA/private/client.key -out demoCA/private/pkcs8_client.key -nocrypt

2.6. 输出文件

server端:ca.crt、server.crt、pkcs8_server.key

client端:ca.crt、client.crt、pkcs8_client.key

3. Java代码

3.1. Server端

  • ServiceMain.java
public class ServiceMain implements CommandLineRunner {
    @Value("${netty.host}")
    private String host;
    @Value("${netty.port}")
    private int port;

    @Resource
    private NettyServer nettyServer;

    public static void main(String[] args) {
        SpringApplication.run(ServiceMain.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        InetSocketAddress address = new InetSocketAddress(host, port);
        ChannelFuture channelFuture = nettyServer.bind(address);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> nettyServer.destroy()));
        channelFuture.channel().closeFuture().syncUninterruptibly();
    }
}
  • NettyServer.java
package cn.a.service.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import java.io.File;
import java.net.InetSocketAddress;

@Slf4j
@Component("nettyServer")
public class NettyServer {

    private final EventLoopGroup parentGroup = new NioEventLoopGroup();
    private final EventLoopGroup childGroup = new NioEventLoopGroup();
    private Channel channel;

    @Resource
    ApplicationContext applicationContext;

    /**
     * 绑定端口
     *
     * @param address
     * @return
     */
    public ChannelFuture bind(InetSocketAddress address) {
        ChannelFuture channelFuture = null;
        try {
            File certChainFile = ResourceUtils.getFile("classpath:server.crt");
            File keyFile = ResourceUtils.getFile("classpath:pkcs8_server.key");
            File rootFile = ResourceUtils.getFile("classpath:ca.crt");
            SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile)
                    .trustManager(rootFile)
                    .clientAuth(ClientAuth.REQUIRE).build();

            ServerBootstrap b = new ServerBootstrap();
            b.group(parentGroup, childGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new NettyChannelInitializer(applicationContext, sslCtx));
            channelFuture = b.bind(address).syncUninterruptibly();
            channel = channelFuture.channel();
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (null != channelFuture && channelFuture.isSuccess()) {
                log.info("netty server start done.");
            } else {
                log.error("netty server start error.");
            }
        }
        return channelFuture;
    }


    /**
     * 销毁
     */
    public void destroy() {
        if (null == channel) return;
        channel.close();
        parentGroup.shutdownGracefully();
        childGroup.shutdownGracefully();
    }


    /**
     * 获取通道
     *
     * @return
     */
    public Channel getChannel() {
        return channel;
    }
}
  • NettyChannelInitializer.java
package cn.a.service.netty;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.ssl.SslContext;
import org.springframework.context.ApplicationContext;

public class NettyChannelInitializer extends ChannelInitializer<SocketChannel> {

    private final ApplicationContext applicationContext;
    private final SslContext sslContext;

    public NettyChannelInitializer(ApplicationContext applicationContext, SslContext sslCtx) {
        this.applicationContext = applicationContext;
        this.sslContext = sslCtx;
    }

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        // 添加SSL安装验证
        channel.pipeline().addLast(sslContext.newHandler(channel.alloc()));
        //发送时编码
        channel.pipeline().addLast(new FrameEncoder());
        //接收时解码
        channel.pipeline().addLast(new FrameDecoder());
        //业务处理器
        channel.pipeline().addLast(new NettyMsgHandler(applicationContext));
    }
}

3.2. Client端

  • TestClientApp.java
package cn.a.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.a.service.netty.FrameDecoder;
import cn.a.service.netty.FrameEncoder;
import cn.a.service.netty.NettyMsg;
import cn.a.service.netty.Session;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.File;
import java.util.Scanner;

@Slf4j
@SpringBootApplication
public class TestClientApp {

    private static final Session session = new Session().setId(IdUtil.randomUUID());

    public static void main(String[] args) {
        new Thread(new TestThread("127.0.0.1", 7890)).start();
    }

    private static class TestThread implements Runnable {
        private final String serverHost;
        private final int serverPort;

        public TestThread(String serverHost, int serverPort) {
            this.serverHost = serverHost;
            this.serverPort = serverPort;
        }

        @Override
        public void run() {
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                final String certsDir = "D:\\GIT\\secim_service\\service\\src\\main\\resources\\";
                File certChainFile = new File(certsDir + "client.crt");
                File keyFile = new File(certsDir + "pkcs8_client.key");
                File rootFile = new File(certsDir + "ca.crt");
                SslContext sslCtx = SslContextBuilder.forClient().keyManager(certChainFile, keyFile).trustManager(rootFile).build();

                Bootstrap b = new Bootstrap();

                b.group(group)
                        .channel(NioSocketChannel.class)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            protected void initChannel(SocketChannel ch) throws Exception {
                                // 添加SSL安装验证
                                ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
                                ch.pipeline().addLast(new FrameEncoder());
                                ch.pipeline().addLast(new FrameDecoder());
                                ch.pipeline().addLast(new TestClientHandler(session));
                            }
                        });

                // 发起异步连接操作
                ChannelFuture f = b.connect(serverHost, serverPort);
                f.addListener(future -> {
                    startConsoleThread(f.channel(), session);
                }).sync();
                // 等待客户端连接关闭
                f.channel().closeFuture().sync();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 优雅退出,释放NIO线程组
                group.shutdownGracefully();
            }
        }
    }

    /**
     * 开启控制台线程
     *
     * @param channel
     */
    private static void startConsoleThread(Channel channel, Session session) {
        new Thread(() -> {
            while (!Thread.interrupted()) {
                log.info("输入指令:");
                Scanner scanner = new Scanner(System.in);
                String input;
                while (!"exit".equals((input = scanner.nextLine()))) {
                    log.info("输入的命令是:{}", input);
                    if (!NumberUtil.isInteger(input)) {
                        log.error("输入的指令有误,请重新输入");
                        continue;
                    }
                    NettyMsg nettyMsg;
                    switch (Integer.parseInt(input)) {
                        case 1:
                            nettyMsg = TestMsgBuilder.buildIdentityMsg(session);
                            break;
                        default:
                            log.error("无法识别的指令:{},请重新输入指令", input);
                            nettyMsg = null;
                            break;
                    }
                    if (null != nettyMsg) {
                        channel.writeAndFlush(nettyMsg);
                    }
                }
            }
        }).start();
    }
}

3.3. 证书存放

在这里插入图片描述

4. 运行效果

4.1. SSL客户端发送消息:

在这里插入图片描述

4.2. 服务器收到SSL客户端消息:

在这里插入图片描述

4.3. 非SSL客户端发送消息:

在这里插入图片描述

4.4. 服务器收到非SSL客户端消息:

在这里插入图片描述

5. References:

2020-07-14 15:01:55 小傅哥:netty案例,netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》

2017-07-04 11:44 骏马金龙:openssl ca(签署和自建CA)

netty中实现双向认证的SSL连接 Edit 1. 前期准备工作 双向证书认证的双方称为client和server,首先为client和server生成证书。由于仅仅是自己学习使用,因此可以在本地自建一个CA,然后用CA的证书分别签发client和server的证书。CA的创建和签发使用OpenSSL。  在windows环境上安装OpenSSL,然后依据OpenSSL目录下的openssl.cnf中[ C 阅读详情

相关推荐

从握手失败到安全通信:Netty SSL双向认证调试全记录(含证书校验原理)

本文详细记录了Netty SSL双向认证从握手失败到成功通信的完整调试过程。文章深入剖析了证书链校验原理,提供了基于OpenSSL的证书生成、Netty正确配置证书链的方法,并分享了通过日志分析、网络抓包定位常见问题的实战经验,是解决TLS双向加密认证问题的实用指南。

weixin_29230901的博客 333

Netty实现SSL双向验证完整实例

 一、证书准备      要使用ssl双向验证,就必须先要生成服务端和客户端的证书,并相互添加信任,具体流程如下(本人调试这个用例的时候,花了很多时间来验证证书是否正确,以及握手失败的原因,这里证书生成过程只要按流程走,本人能保证绝对没有问题) 现在打开cmd,在哪个目录下打开,证书就会放在哪个目录下: 第一步:   生成Netty服务端私钥和证书仓库命令  keytool -genk...

dw147258dw的专栏 850

Netty与OpenSSL实战:构建双向TLS/SSL认证的安全通信管道

本文详细介绍了如何使用Netty与OpenSSL构建支持双向TLS/SSL认证的安全通信管道。通过实战演示,从生成CA根证书、服务器与客户端证书,到配置Netty服务端与客户端实现强制双向加密认证,并深入解析了握手过程、证书验证及生产环境进阶考量,为金融、物联网等高安全需求场景提供了一套完整的安全通信解决方案。

weixin_29219539的博客 226

Netty进行SSL认证

第一步: 生成Netty服务端私钥和证书仓库命令,用于将客户端的证书保存到服务端的授信证书仓库中 keytool -genkey -alias securechat -keysize 2048 -validity 365 -keyalg RSA -dname "CN=localhost" -keypass sNetty -storepass sNetty -keystore sChat.jks 第二步:生成Netty服务端自签名证书 用于颁给使用者 从 证书仓库中导出证书 keytool -e...

drsbbbl的博客 5011

Netty实战:从零构建TLS/SSL双向认证的安全通信通道

本文详细介绍了如何使用Netty构建TLS/SSL双向认证的安全通信通道,涵盖证书生成、服务端与客户端配置、证书验证及性能优化等关键步骤。通过实战案例,帮助开发者快速实现双向加密认证,确保网络通信的安全性,适用于金融、医疗等高安全要求的场景。

weixin_29232507的博客 278

Netty使用SSL实现双向通信加密

最近项目有个需求,TCP服务器实现基于证书通信加密,之前没做过,花了一些时间调研,今天整理下。

我是香菜 2107

Netty实现SSL双向验证

Netty实现SSL双向验证 一、证书准备 要使用ssl双向验证,就必须先要生成服务端和客户端的证书,并相互添加信任,具体流程如下(本人调试这个用例的时候,花了很多时间来验证证书是否正确,以及握手失败的原因,这里证书生成过程只要按流程走,本人能保证绝对没有问题) 现在打开cmd,在哪个目...

u014066037的博客 1416

netty案例,netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》

前言介绍 SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。 在实际通信过程中,如果不使用SSL那么信息就是明文传输,从而给非法分子一些可乘之机; 窃听风险[eavesdropping]:第三方可以获知通信内容...

bugstack虫洞栈 2549

netty集成ssl双向验证

netty集成ssl双向验证 文章分为两部分, 生成服务器和客户端两个证书 将证应用到netty中 生成证书用到jak自带的工具,一会再讲,先看如果假设我们已经有两个证书(服务器和客户端)如何写程序 服务器上要添加sslhandler,参数是sslEngine,而engine由sslContext创建 p.addLast(new SslHandler(context.newEngine...

woaiqianzhige的博客 2542

深入解析YT8521S千兆以太网PHY芯片的设计与调试要点

本文深入解析了YT8521S千兆以太网PHY芯片的设计与调试要点。重点剖析了硬件设计中的电源方案、RGMII接口电平配置(尤其是1.8V电平方案)以及PCB布局布线等关键细节,并提供了从硬件检查、驱动配置到性能测试的完整调试流程,帮助工程师规避常见陷阱,实现稳定可靠的千兆网络连接。

weixin_29190573的博客 685

HUMAnN数据库国内备份下载源(转自刘永鑫博士github)

百度云链接 R语言常用包合集 Windows 10版4.0.x:链接:https://pan.baidu.com/s/1JFwLP2SonK1howD5MNgNYg 提取码:l08k Windows 10版3.6.x:链接:https://pan.baidu.com/s/1h-qR2lmlaMgR4M7VbgtAFg 提取码:s5fi 下载后解压至当前目录,可获得3.6/4.0目录,剪切并替换文档 - R - win-library - 3.6/4.0 目录即可 扩增子数据库 宏基因组数据库 HUM.

zlabx的博客 3241

spring gateway 使用netty服务器启用ssl双向验证

spring gateway 使用netty服务器启用ssl双向验证

Java练习生蔡广坤 923

不用买VR设备!用UE5内置模拟器开发虚拟现实项目的完整教程

本文提供了一套无需购买昂贵VR硬件的虚拟现实开发最佳实践方案。详细介绍了如何利用虚幻引擎5内置的XR模拟器,从零开始配置开发环境、模拟操作、构建场景并实现核心交互逻辑。通过这套纯软件方案,开发者可以高效学习VR开发核心,大幅降低入门门槛和成本。

weixin_29019241的博客 611

netty 校验_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 1024openssl genrsa -des3 -out client.key 10243.根据...

weixin_39624769的博客 361

比NTP还牛逼的时间同步协议:1588v2,亚微秒级!

1588v2,又称为Precision Time Protocol Version 2,即精密时间协议的第二版本,或称为PTPv2,是一种精密时间同步协议标准,旨在实现网络中设备之间的高精度时间同步。该协议由IEEE标准组织发布,并在网络测量和控制系统中得到广泛应用。1588v2的主要目的是在计算机网络中提供高度准确的时间同步。它可用于确保不同设备之间的时钟同步,从而协调它们的操作。这对于需要协同工作的系统、无线通信基站等具有关键性的应用非常重要。

网络技术联盟站 4279

Python 实战:爬取高德地图交通数据(路况拥堵指数分析)

高德地图是由高德软件有限公司开发的一款地图导航产品,提供详细的地图浏览、路线规划、实时路况、公共交通查询等功能。高德地图拥有庞大的用户群体和海量的交通数据,这些数据对于交通管理、城市规划、出行服务等领域具有重要的价值。通过对高德地图交通数据的分析,我们可以了解城市交通的运行状况,识别拥堵路段,预测交通流量,为交通管理部门和出行者提供决策支持。

yansideyucsdn的博客 2684

cryptapi双向认证_2019 08 28 netty案例,netty4.1中级拓展篇十三《Netty基于SSL实现信息传输过程中双向加密验证》...

沉淀、分享、成长,让自己和他人都能有所收获!前言介绍SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。在实际通信过程中,如果不使用SSL那么信息就是明文传输,从而给非法分子一些可乘之机;窃听风险[eavesdropp...

weixin_39956612的博客 359

Linux Kernel入门到精通系列讲解(RV-Kernel 篇) 5.5 RTC设备编写与实现

4. Linux kernel RTC子系统goldfish_rtc driver分析。电脑,会需要时间,还比如 我们的手机、平板,都需要时间;驱动基本就是应用层需要什么数据你给什么数据就行,基本必须实现的就是。3.2 Linux kernel RTC 设备描述符讲解。中看到他的具体实现,也可以根据他的寄存器描述直接在。5. 将驱动添加进kernel和测试RTC驱动。系统来说,时间是一个非常重要的功能;之类的函数接口,接下来我们就开始讲解如何写。,所以我们直接移植设备树即可。,他的寄存器很简单,你可以从。

DSMGUOGUO的博客 568

Netty实现SSL/TSL双向加密认证示例

Netty实现SSL/TSL双向加密认证示例 去发现同类优质开源项目:https://gitcode.com/ 此项目为一个基于Netty实现的SSL/TLS双向加密认证的服务器和客户端简单示例。本示例使用IDEA开发工具创建,可以直接导入至IDEA中进行开发。 项目简介 本项目展示了如何在Netty框架下建立SSL双向加密的服务器端和客户端。通过该示例,您可以了解到如何在Netty网络通信过程中...

gitblog_06740的博客 325

【YOLOv13[基础]】热力图可视化实践 | 脚本升级 | 优化可视化效果 | 论文必备 | GradCAMPlusPlus, GradCAM, XGradCAM, EigenCAM等

本文将进行添加YOLOv13版本的升级版热力图可视化功能的实践,支持图像热力图可视化、优化可视化效果、 可以选择使用GradCAMPlusPlus, GradCAM, XGradCAM, EigenCAM, HiResCAM, LayerCAM, RandomCAM, EigenGradCAM。一个参数即可设置是否显示检测框等。

静谧、淡雅 644

基于matlab的轴承损伤分析动力学建模仿真

高质量的轴承在正确的使用下,可以使用很长一段时间,如果过早的出现损伤,很可能是因为选型错误,使用不当或润滑不良造成的。因此,在安装轴承时,我们需要记录机器种类,安装部位,使用条件及周围配合。通过研究总结轴承损伤的类型,发生问题时的使用环境,以避免类似情况再次发生。轴承损伤方式按下述图片分类,我们可以图片中显示的主要特征来判断轴承损伤形式。01、压痕碰伤卡入固体异物或冲击造成的表面凹坑及安装是的擦伤◆固体异物侵入◆在倾斜状态下安装◆安装不良造成的撞击,脱落◆卡入剥离片◆改善安装、使用方法。

平时工作较为繁忙,私信消息一般晚上回复,谢谢大家~~ 2667

java架构师认证_java架构师学习路线-Netty4如何实现SSL双向认证

Netty是人们网络编程常用的框架之一,并且随着人们对安全性的重视,SSL协议已经成为人们普遍使用的安全协议。本文就向大家介绍一下Netty4如何实现SSL双向认证,保证通信时的信息安全。1、因为最初使用的netty版本为4.0.23,实现SSL的双向认证相当麻烦。所以就将netty版本升级为4.0.34,此版本对SSL连接的建立做了比较大的优化,实现SSL双向认证得到了极大的简化,并且升级后对原...

weixin_30186743的博客 371

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: frida基础命令
下一篇: USBasp给arduino nano烧写bootloader
相信光的疯子
博客等级 码龄18年 91粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值