有效证书上的 JDK 11 SSL 错误(在以前的版本中工作)

Posted

技术标签:

【中文标题】有效证书上的 JDK 11 SSL 错误(在以前的版本中工作)【英文标题】:JDK 11 SSL Error on valid certificate (working in previous versions) 【发布时间】:2019-01-31 15:22:04 【问题描述】:

以下代码在 JDK 11 中引发错误:

    HttpURLConnection con = (HttpURLConnection) new URL("https://sis.redsys.es/sis/realizarPago").openConnection();
    con.setRequestMethod("GET");
    con.getResponseCode();

错误是:

javax.net.ssl.SSLHandshakeException: extension (10) should not be presented in server_hello
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:312)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:268)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
at java.base/sun.security.ssl.SSLExtensions.<init>(SSLExtensions.java:71)
at java.base/sun.security.ssl.ServerHello$ServerHelloMessage.<init>(ServerHello.java:169)
at java.base/sun.security.ssl.ServerHello$ServerHelloConsumer.consume(ServerHello.java:860)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:390)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:445)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:877)
at java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:810)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:383)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)

它可以在任何以前的 JDK 中工作(我已经在 7、8、9 和 10 中测试过)。

该证书似乎是有效的,因为它被浏览器或我在互联网上找到的大多数 SSL 测试所识别。

我尝试禁用主机名验证、禁用 cacerts、将 DigiCert 添加到 cacerts 文件,但没有任何运气。

这似乎是 openJDK 中的一个错误。在版本 26、27 和 28(候选版本)中测试。

【问题讨论】:

这似乎是服务器的问题。到目前为止,它已被所有客户端接受,但 OpenSSL 和其他已开始对允许的内容更加严格:mta.openssl.org/pipermail/openssl-dev/2017-October/009802.html 我明白,但是没有兼容性标志(我在源代码中看不到任何东西)。因此,除了等待他们修复他们的证书(这可能需要很长时间)或创建一个“代理”服务器来绕过证书之外,没有其他解决方法。这阻碍了我们升级到 java 11,它是西班牙广泛使用的支付系统 不是证书而是服务器在 SERVER_HELLO 消息中发送了不正确的数据。 对不起,你是对的。我会写的,看看他们能不能解决。 bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8209982 【参考方案1】:

该问题目前已在 JDK 12 https://bugs.openjdk.java.net/browse/JDK-8209965 中得到解决,并已包含在 ea-9 中。

JDK 11 的反向移植也已解决 https://bugs.openjdk.java.net/browse/JDK-8210005 并包含在

11.0.3 (Oracle JDK) 11.0.2 (OpenJDK)

可以在此处的 cmets https://github.com/openssl/openssl/pull/4463/files 中找到一些背景信息

TLS 1.3 为服务器增加了一个方案来指示 向客户提供其支持的组列表 EncryptedExtensions 消息,但没有相关的 规范允许在 ServerHello 中发送supported_groups。

尽管如此(可能是由于靠近 "ec_point_formats" 扩展,在 ServerHello 中允许), 有几台服务器在 无论如何,ServerHello。

直到并包括 1.1.0 版本, 我们没有检查是否存在未经许可的扩展, 所以为了避免回归,我们必须在 TLS 1.2 ServerHello 也是如此。

【讨论】:

【参考方案2】:

现在已在 2019 年 1 月 16 日发布的 JDK 11.0.2 中解决

【讨论】:

11.0.2真的解决了吗?正如人们所说的那样会在11.0.3解决? 可能是另一种情况 不,不是。至少在 openjdk 中没有。 解决了,有反例吗?您是否尝试过问题中的示例?为什么说没有解决? 不,不是。可能会针对您的情况解决,而不是针对所有情况。

以上是关于有效证书上的 JDK 11 SSL 错误(在以前的版本中工作)的主要内容,如果未能解决你的问题,请参考以下文章

在 QWebSockets 中检查客户端 SSL 证书有效性的最佳实践

SSL证书无效怎么解决

WSS over Secure SSL 连接仅在 FireFox 上失败,错误 1006

安装好alphassl ssl证书却提示证书有错误?

JAVA - SSL - 客户端证书

Android webview 获取 sslError SSL_UNTRUSTED 但证书有效