netss SSL处理程序在badssl.com上未正确失败

时间:2016-09-12 13:41:22

标签: java android ssl ssl-certificate netty

我正在开发一个使用Netty来管理其SSL / TLS连接的应用程序。我正在尝试测试它是否正确处理了各种证书错误,我使用badssl.com。

但是,当我尝试连接到badssl.com时,会抛出异常(为了简洁和清晰起见,编辑并删除了完整的callstack跟踪):

 An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
    io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Handshake failed
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:442)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:372)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:358)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:350)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)

...
    Caused by: javax.net.ssl.SSLHandshakeException: Handshake failed
        at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:436)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1006)
        at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1094)

...

    Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:318)
        at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219)
...
    Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:318) 
        at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219) 
        at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:113)

以下guide for Android developers links Trust anchor for certification path not found.个例外,其中包含未识别的CA,自签名证书或缺少中间CA.但这不是badssl.com的情况 - 手机的浏览器识别证书,我甚至可以成功使用HTTPSUrlConnection来联系它。

当我使用InsecureTrustManagerFactory.INSTANCE来初始化我的安全性时,Netty连接成功,但这不是一个长期的解决方案。

以下是相关的代码段: 初始化SslContext

    sslContext = SslContextBuilder
            .forClient()
            .sslProvider(SslProvider.JDK)
            // TODO p0: Ensure all the versions we support have this algorithm installed
            //.trustManager(InsecureTrustManagerFactory.INSTANCE)
            .build();

添加SSL处理程序:

ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(sslContext.newHandler(ch.alloc(), host.getHostName(), host.getPort()));

验证后写入HTTP请求:

            ChannelFuture future = bootstrap.connect(host).addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    String request = "GET https://badssl.com/\n" +
                            "Host: +" + host.getHostName() + "\n" +
                            "Accept: text/html,application/xhtml+xml,application/xml;"
                            + "DNT: 1\n\n";

                    future.channel().writeAndFlush(Unpooled.copiedBuffer(
                            request, Charset.forName("ASCII")));
                }

这里发生了什么?为什么badssl.com不被认可?我还尝试了一些具有已知错误证书的域,其中连接似乎错误地成功。为SSL客户端提供的唯一示例是SecureChatClient,它使用InsecureTrustManager。

我正在使用Netty 4.1,我的测试手机是带有Android 5.0的LG G3。

1 个答案:

答案 0 :(得分:0)

我的猜测是您的代码不使用Server Name Indication (SNI)。在这种情况下,对badssl.com的TLS握手将产生证书:

Subject: ...CN=badssl-fallback-unknown-subdomain-or-no-sni
Issuer:  ...CN=BadSSL Intermediate Certificate Authority

此证书由BadSSL本身颁发,并且代码正确地抱怨未找到证书路径的信任锚,因为此证书未由受信任的CA签名。

  

..我甚至可以成功使用HTTPSUrlConnection ..

HTTPSUrlConnection使用SNI,服务器发送由受信任的CA签名的其他证书:

Subject: ... CN=*.badssl.com
Issuer:  ... CN=COMODO RSA Domain Validation Secure Server CA

不幸的是,关于如何在客户端使用SNI的文档似乎很少见,但看起来缺少支持在后续版本的Netty中出现问题others noticed toomaybe there is fix