openssl 自建证书

openssl 自建证书

背景

前提需要openssl 版本>1.1.1

最近做一个项目需要使用wss协议、类似与https,访问加密需要证书相关。了解了下证书相关内容记录一下。

根证书

1. 生成根证书私钥 (ECC 256 位,安全且性能好)

bash 复制代码
openssl ecparam -name prime256v1 -genkey -noout -out ca-key.pem

2. 生成根证书 (有效期 10 年)

bash 复制代码
openssl req -x509 -new -nodes -key ca-key.pem -sha256 -days 3650 \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyPrivateCA/CN=My Root CA" \
  -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
  -addext "keyUsage=critical,keyCertSign,cRLSign" \
  -out ca-cert.crt

服务器证书

1. 生成服务器私钥

⚠️RSA 2048 位,兼容性最好

bash 复制代码
openssl genrsa -out server-key.pem 2048

2. 生成证书签名请求 (CSR)

⚠️ CN 请改成你自己的域名或 IP,例如 localhost 或 192.168.1.100

bash 复制代码
openssl req -new -key server-key.pem -sha256 \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MyPrivateCA/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" \
  -out server.csr

3. 用根证书签署服务器证书 (有效期 1 年)

bash 复制代码
openssl x509 -req -in server.csr -CA ca-cert.crt -CAkey ca-key.pem \
  -CAcreateserial -out server-cert.crt -days 365 -sha256 \
  -copy_extensions copy

验证证书

查看服务器证书内容

bash 复制代码
openssl x509 -in server-cert.crt -text -noout

验证证书链(应该显示 ok)

bash 复制代码
openssl verify -CAfile ca-cert.crt server-cert.crt

浏览器导入根证书

双击 ca-cert.crt → 选择"安装证书"

选择"本地计算机"(需要管理员权限)→ 下一步

选择"将所有的证书放入下列存储" → 点击"浏览"

选择"受信任的根证书颁发机构" → 确定 → 下一步 → 完成

重启浏览器(完全退出再打开)

Netty开启wss

证书处理

Netty 的 forServer(File certChainFile, File keyFile) 第一个文件必须是完整的证书链,顺序为:服务器证书 → 根证书。

bash 复制代码
cat server-cert.crt ca-cert.crt > fullchain.crt
  1. 转换为 PKCS#8 格式
bash 复制代码
openssl pkcs8 -topk8 -nocrypt -in server-key.pem -out server-key-pkcs8.pem

代码更改

java 复制代码
public void start() {

        bossGroup = new NioEventLoopGroup(1);
        workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            try {
                                SslContext sslContext = SslContextBuilder.forServer(
                                        new File("D:\\code\\ca\\fullchain.crt"),
                                        new File("D:\\code\\ca\\server-key-pkcs8.pem")
                                ).build();
                                ch.pipeline().addLast(sslContext.newHandler(ch.alloc()));
                            } catch (SSLException e) {
                                log.info("SslContext init failed !!!");
                            }

                            ch.pipeline().addLast(new HttpServerCodec());
                            ch.pipeline().addLast(new ChunkedWriteHandler());
                            ch.pipeline().addLast(new HttpObjectAggregator(65536));
                            ch.pipeline().addLast(new WebSocketServerProtocolHandler(path, null, true, 10 * 1024 * 1024));
                            ch.pipeline().addLast(webSocketFrameHandler);
                        }
                    });

            ChannelFuture f = b.bind(port).sync();
            log.info("Netty WebSocket Server started on port: {}", port);
            // f.channel().closeFuture().sync(); // Don't block here as it's called from Spring's main thread
        } catch (InterruptedException e) {
            log.error("Netty WebSocket Server interrupted", e);
            Thread.currentThread().interrupt();
        }
    }

验证结果

总结

基本流程

获取证书链:你访问 https:// 网站时,服务器会发送它的"服务器证书"以及所有必要的中间证书。如果网站证书缺少了关键的中间证书,浏览器就可能发出"连接不安全"的警告。

构建信任链:浏览器收到后,会尝试从"服务器证书"开始,一级一级地向上追溯签发者,直到找到一个它内置信任的"根证书"。这就构建了一条完整的信任链。

逐级验证签名:浏览器会从根证书开始,逐级向下验证签名。它会用上级证书的公钥,去解密和验证下一级证书的签名,以此来确认下一级证书确实是由自己签发的、内容没有被篡改。只要能成功追溯到受信任的根,链条就是有效的。

检查证书内容:在验证签名有效后,浏览器还会检查证书里的关键信息,是否与实际相符:

有效期:证书是否在有效期内。

域名匹配:证书里的域名是否和你浏览器地址栏里的域名完全一致。

是否被吊销:浏览器可能会通过在线证书状态协议(OCSP) 等方式,检查证书是否被颁发机构提前注销了。

netty使用wss

1、生成根证书(CA)和私钥(可用 openssl 命令)。
2、生成服务器证书私钥(RSA 或 EC),并转换为 PKCS#8。
3、用根证书签发服务器证书,得到 server-cert.crt。
4、将 server-cert.crt 和 ca-cert.crt 合并为 fullchain.crt(顺序:服务器证书在前,根证书在后)。
5、Netty 服务端配置:

java 复制代码
SslContext sslCtx = SslContextBuilder.forServer(
        new File("/path/to/fullchain.crt"),
        new File("/path/to/server-key-pkcs8.pem")
).build();

6、将 ca-cert.crt 分发给所有客户端,并指导它们安装到受信任根证书存储区。
7、客户端使用 wss://your-server-domain 访问,一切正常。

相关推荐
需要82612 分钟前
MySQL 索引 B+ 树与“查询为什么变慢了
java·spring boot·spring·spring cloud·tomcat
一 乐13 分钟前
二手交易平台|基于springboot + vue二手交易平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·小程序
万年咸鱼18 分钟前
编译Java源程序
java
Wang's Blog33 分钟前
Java 项目实战: 外卖平台-删除分类的关联校验与自定义业务异常
java·服务器·项目开发
hai_android41 分钟前
Kotlin / Android 常用函数使用示例手册
android·java·kotlin
MayBaymax1 小时前
MongoDB 索引与事务
java·数据库·mongodb
vx-程序开发1 小时前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django
勇气要爆发1 小时前
006.注解
java·注解
liuchangng2 小时前
Jev 模型研究:从生成式大模型到决策式模型——System One、RLCD 校准与采用边界
java·javascript·人工智能·python·深度学习
GPU实战笔记2 小时前
本地跑不动 llama.cpp,临时租云 GPU 怎么搭?从启动服务到环境复用
java·服务器·网络·人工智能·深度学习·llama