Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 1.8:TLSv1.2 ClientHello握手失败(缺少椭圆曲线扩展?)_Java_Macos_Ssl_Bouncycastle_Okhttp3 - Fatal编程技术网

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

Java 1.8:TLSv1.2 ClientHello握手失败(缺少椭圆曲线扩展?),java,macos,ssl,bouncycastle,okhttp3,Java,Macos,Ssl,Bouncycastle,Okhttp3,我使用java1.8,通过OKHTTP连接到APNS(api.push.apple.com) 症状是SSL握手失败:javax.net.SSL.SSLHandshakeException:收到致命警报:握手失败,根据我的研究,这表明服务器无法与客户端协商密码 代码只是通过SSLContext.getInstance(“TLS”)创建SSL上下文 使用-Djavax.net.debug=all运行应用程序后,我发现我的SSL握手客户端如下所示: *** ClientHello, TLSv1.2 R

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

症状是SSL握手失败:
javax.net.SSL.SSLHandshakeException:收到致命警报:握手失败
,根据我的研究,这表明服务器无法与客户端协商密码

代码只是通过
SSLContext.getInstance(“TLS”)
创建SSL上下文

使用
-Djavax.net.debug=all
运行应用程序后,我发现我的SSL握手客户端如下所示:

*** 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]
***

令人费解的是,代码在同事的笔记本电脑上成功运行-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表明,它只接受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握手中缺少的
扩展名
s导致服务器拒绝我的握手,因为没有通用密码可供使用


运行它的笔记本电脑是OSX10.10,而坏掉的是MacOS10.12。我们都在Java1.8上


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


感谢您的时间。

可能是缺少EC扩展导致了问题,尽管在技术上是允许的-请参阅RFC 4492第4节:

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

这仍然可能出错,但可能不是在您收到服务器的第一次航班(ServerHello…ServerHelloDone)之前,因此我假设服务器不允许这种缺席

我认为JDK8不发送该扩展是非常奇怪的行为,因此我希望您的JDK在某种程度上配置得很奇怪,最好安装并测试一个全新的JDK8(除了安装“JCE无限强度”策略文件外,未经修改)

我简要地看了一下(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版本:

所有ALPN罐可在此处找到:

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