繁体   English   中英

Java 1.8:TLSv1.2 ClientHello握手失败(缺少椭圆曲线扩展?)

[英]Java 1.8: TLSv1.2 ClientHello handshake failure (missing elliptical curve extensions?)

我正在使用java1.8,并通过OKHTTP连接到APNS(api.push.apple.com)。

症状是SSL握手失败: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure ,根据我的研究,这表明服务器无法与客户端协商密码。

该代码只是通过SSLContext.getInstance("TLS")创建一个SSL上下文。

使用-Djavax.net.debug=all运行我的应用程序后,我发现我的SSL握手ClientHello看起来像这样:

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1500317763 bytes = { 59, 94, 246, 29, 243, 123, 94, 45, 2, 86, 47, 12, 198, 219, 164, 71, 166, 30, 143, 25, 190, 34, 243, 50, 24, 239, 0, 131 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
Compression Methods:  { 0 }
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension server_name, server_name: [type=host_name (0), value=api.push.apple.com]
Extension renegotiation_info, renegotiated_connection: <empty>
Extension application_layer_protocol_negotiation, protocols: [h2, spdy/3.1, http/1.1]
***

基本上只是跟着一个

OkHttp https://api.push.apple.com/3/device/token, READ: TLSv1.2 Alert, length = 2
OkHttp https://api.push.apple.com/3/device/token, RECV TLSv1.2 ALERT:  fatal, handshake_failure

令人费解的是,该代码已在同事的便携式计算机上成功运行-SSL ClientHello完全相同,但其中包括以下两个条目:

Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]

分析APNS服务器的SSL( https://www.ssllabs.com/ssltest/analyze.html?d=api.push.apple.com&s=17.188.154.31 )显示,它仅接受TLSv1.2和以下密码:

TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)   ECDH secp256r1 (eq. 3072 bits RSA)   FS  256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH secp256r1 (eq. 3072 bits RSA)   FS    256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)   ECDH secp256r1 (eq. 3072 bits RSA)   FS    128

这使我认为SSL握手中缺少的Extension导致服务器在没有通用密码的基础上拒绝了我的握手。


运行该操作系统的笔记本电脑是OS X 10.10,而损坏的笔记本电脑是macOS 10.12。 我们都在Java1.8上。


如果有人对此有任何线索,将不胜感激。

谢谢你的时间。

造成问题的原因可能是缺少EC扩展名,尽管从技术上讲是允许的-请参阅RFC 4492第4节:

提出ECC密码套件的客户端可以选择不包括这些扩展。 在这种情况下,服务器可以自由选择第5节中列出的任何椭圆曲线或点格式。

这仍然可能会出错,但是大概在您没有收到服务器的第一次运行之前(ServerHello ... ServerHelloDone),因此我认为服务器不允许这种情况。

我认为JDK8不发送该扩展名是很奇怪的行为,因此我希望您的JDK以某种方式进行了奇怪的配置,因此最好安装和测试全新的JDK8(未经修改,除了安装“ JCE Unlimited Strength”外)策略文件)。

我简要地看了一下(OpenJDK)JDK8源码,为什么有这种扩展的原因也有两种可能:

  • 不知何故,“ EC”的JCE加密提供程序丢失或不支持TLS曲线。 查看您的security.provider条目的jre / lib / security / java.security列表,以及您正在进行的任何编程提供程序更改。 您是否要使用某种硬件令牌进行客户端身份验证?
  • 也许您已经设置了“ jdk.tls.namedGroups”系统属性(如果为空,则应该会看到一个例外,但可能仅列出了不受支持的曲线)。 检查您可能已设置的任何其他系统属性。

根据源代码,由于找不到任何曲线而在调试日志中可能会出现一行:

        if (debug != null && idList.isEmpty()) {
        debug.println(
            "Initialized [jdk.tls.namedGroups|default] list contains " +
            "no available elliptic curves. " +
            (property != null ? "(" + property + ")" : "[Default]"));
    }

请报告您是否看到该消息及其内容。 了解您正在使用的确切JDK8版本以及是否启用了FIPS模式也可能会有所帮助。

您的启动类路径中的ALPN库将用修补版本替换JDK中的SSL代码。 这意味着您将在更新JDK并且ALPN保持旧版本时破坏JDK!

在映射文件中检查JDK所需的ALPN版本: https : //github.com/jetty-project/jetty-alpn/tree/master/docs

可以在这里找到所有的ALPN JAR: http : //repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM