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 访问,一切正常。

相关推荐
面汤放盐1 小时前
何时使用以及何时不应使用微服务:没有银弹
java·运维·云计算
0xDevNull1 小时前
Spring Boot 自动装配:从原理到实践
java·spring boot·后端
qq_589568102 小时前
java学习笔记,包括idea快捷键
java·ide·intellij-idea
小怪吴吴3 小时前
idea 开发Android
android·java·intellij-idea
嘻嘻哈哈樱桃3 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划
一次旅行3 小时前
IDEA安装CC GUI新手指南
java·ide·intellij-idea
超梦dasgg3 小时前
Spring AI 智能航空助手项目实战
java·人工智能·后端·spring·ai编程
counting money4 小时前
Spring框架基础(配置篇)
java·后端·spring
秋95 小时前
OceanBase与GreatSQL在Java应用中的性能调优方法有哪些?
java·开发语言·oceanbase