如何将证书链添加到 netty 服务器?

How can I add certificate chain to netty server?

我为我的域购买了证书(来自 comodo),它包含 3 个文件:私钥、证书和 ca-bundle 文件。

我将它添加到我的 apache server/mod_ssl 它工作得很好。我可以轻松配置,因为它有 3 个配置参数:SSLCertificateFile、SSLCertificateKeyFile、SSLCertificateChainFile。

我正在尝试添加到我的其他 java 应用程序,使用 Netty 作为网络库。 以下是我的服务器代码:

SslContext sslContext = null;
File cert = new File(Config.CERT_FILE_PATH);
File key = new File(Config.KEY_FILE_PATH);
sslContext = SslContextBuilder.forServer(cert, key).build();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .localAddress(port)
        .childOption(ChannelOption.TCP_NODELAY, true)
        .childOption(ChannelOption.SO_KEEPALIVE, true)
        .childHandler(new WebServerInitializer(sslCtx));
Channel ch = b.bind().sync().channel();

其中Config.CERT_FILE_PATH是我的证书文件路径,Config.KEY_FILE_PATH是我的私钥文件路径。

但问题是一些浏览器说证书错误(更多详细信息是 Chrome on mac os,浏览器不信任我的证书)。

我做了一些研究,发现我的 netty http 服务器没有向客户端发送完整的证书链(包含我的证书的中间证书),它只发送我的证书(我通过 KeyStore Explorer 工具检查)。

我尝试将 Config.CERT_FILE_PATH 值替换为 ca-bundle 文件的路径或将证书文件的值附加到 ca-bundle 文件并使用新文件,但仍然不成功。抛出异常:

io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: Received fatal alert: decrypt_error
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:358)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
        at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:112)
        at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
        at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLException: Received fatal alert: decrypt_error
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1646)
        at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1614)
        at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1780)
        at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1075)
        at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:901)
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:775)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1135)
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1025)
        at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:965)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:327)
        ... 12 more

如何正确地将带有ca-bundle的证书添加到netty服务器?

为什么其他浏览器(windows 和 mac 上的所有浏览器,mac 上的 chromium base 浏览器除外)仍然可以使用我的错误服务器?

您究竟是如何连接这些文件的?如果您访问 public,我建议您访问 What's My Chain Cert? 并下载正确的链(保持 "Include Root Certificate" 未选中)。使用此文件作为您的 cert.

至于为什么该站点可以在大多数浏览器中运行而在某些浏览器中不能运行,see this answer

您可以使用 SSL Labs 诊断任何证书和 SSL 相关问题。