【问题标题】:Java 8 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated, but not Java 7Java 8 javax.net.ssl.SSLPeerUnverifiedException:对等体未通过身份验证,但不是 Java 7
【发布时间】:2014-07-28 23:25:12
【问题描述】:

将我的应用程序从 Java 7 切换到 Java 8 时遇到问题。更改 JDK 后,我开始收到此 SSLPeerUnverified 异常。改回Java7,也不例外。

我发现了这个问题:SSL connection failing for Java 7,这意味着这可能与服务器端问题有关。我们的服务器确实在 Ubuntu 机器上运行,但它也在运行 Java8(sun Java8)

不确定还有什么对发布有帮助。如果需要/有用,我可以提供代码示例。我现在没有包含它们,因为看起来好像代码不是问题。

编辑 - 链接到我的 SSLSocketFactory 扩展:http://pastebin.com/2j6HDHE7

Edit2 - Http 客户端代码:

    private HttpClient getHttpClient() throws GeneralSecurityException, IOException {
        final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());

        trustStore.load(CommandChannel.class.getResourceAsStream("myKeystore"), "myPassword".toCharArray());

        final SSLSocketFactory sslSocketFactory = new TrustingSSLSocketFactory(trustStore);

        final SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
        registry.register(new Scheme("https", 443, sslSocketFactory));

        final HttpParams params = new BasicHttpParams();
        HttpProtocolParamBean paramsBean = new HttpProtocolParamBean(params);
        paramsBean.setVersion(HttpVersion.HTTP_1_1);
        paramsBean.setContentCharset("UTF_8");

        final ClientConnectionManager ccm = new BasicClientConnectionManager(registry);
        final DefaultHttpClient httpClient = new DefaultHttpClient(ccm, params);

        return httpClient;
    }

包括下面 java8 和 java7 的 SSL 调试信息。

Java 8 SSL 调试跟踪:

%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1389745002 bytes = { 220, 201, 110, 4, 38, 166, 25, 166, 235, 253, 71, 242, 226, 124, 22, 149, 28, 207, 242, 25, 201, 123, 218, 56, 207, 67, 195, 17 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
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]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA, MD5withRSA
***
JavaFX Application Thread, WRITE: TLSv1.2 Handshake, length = 207
JavaFX Application Thread, received EOFException: error
JavaFX Application Thread, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
JavaFX Application Thread, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
JavaFX Application Thread, WRITE: TLSv1.2 Alert, length = 2
JavaFX Application Thread, called closeSocket()
JavaFX Application Thread, IOException in getSession():  javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
JavaFX Application Thread, called close()
JavaFX Application Thread, called closeInternal(true)
JavaFX Application Thread, called close()
JavaFX Application Thread, called closeInternal(true)
18:49:14,951 ERROR [logger] [LoginController] Error logging in due to: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
com.limebrokerage.portal.communication.command.CommandChannelException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

同一位代码的 Java 7 SSL 调试跟踪:

%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1389746267 bytes = { 91, 88, 192, 29, 58, 48, 211, 105, 40, 40, 138, 204, 154, 113, 233, 213, 120, 99, 3, 223, 26, 233, 123, 150, 251, 245, 186, 246 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
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]
***
JavaFX Application Thread, WRITE: TLSv1 Handshake, length = 149
JavaFX Application Thread, READ: TLSv1 Handshake, length = 74
*** ServerHello, TLSv1
RandomCookie:  GMT: 1389746267 bytes = { 179, 44, 184, 192, 189, 56, 33, 48, 248, 204, 248, 129, 1, 214, 77, 185, 206, 200, 3, 148, 58, 49, 98, 42, 213, 229, 106, 218 }
Session ID:  {83, 214, 216, 91, 179, 44, 184, 192, 189, 56, 33, 48, 248, 204, 248, 129, 1, 214, 77, 185, 206, 200, 3, 148, 58, 49, 98, 42, 213, 229, 106, 218}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
***
Warning: No renegotiation indication extension in ServerHello
%% Initialized:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
JavaFX Application Thread, READ: TLSv1 Handshake, length = 1522
*** Certificate chain
chain [0] = [
[
  Version: V3

【问题讨论】:

  • 服务器的 URL 是什么?
  • 您在服务器上使用任何自签名证书吗?如果是,则需要手动添加到 JDK 的钥匙串
  • @dimoniy - 服务器上没有自签名证书。服务器拥有由威瑞信签署的证书(2017 年到期)
  • 查看一段代码可能很有用:SSLSocketSSLEngineHttpsURLConnection?你是否明确地开始握手?客户端上的 Java 8 和服务器上的 Java 7 是否会发生这种情况?
  • @Bruno - 添加了示例代码 - 我可以提供更多,但这些似乎是最相关的部分。

标签: java ssl java-8


【解决方案1】:

不确定答案,但评论太长了。

你真正的问题是你好服务器断开连接并导致SSLHandshakeException; SSLPeerUnverifiedException 是附带损害,因为握手未达到身份验证阶段。明显的区别是 Java 8 发送的是 TLSv1.2 ClientHello,而 Java 7 发送的是 TLSv1。

Java 7 实现了 1.1 和 1.2,但默认情况下没有在客户端启用它们; 8 确实如此,请参阅 https://bugs.openjdk.java.net/browse/JDK-7093640 。不支持 1.2 的正确编写的服务器堆栈应该协商到 1.1 或 1(.0),但您的身份不明的服务器显然不支持,或者可能是防火墙之类的中间设备正在搞砸连接起来。如果您拥有或获得 OpenSSL,命令行openssl s_client 将让您轻松尝试不同的版本(以及密码和一些选项),以查看哪些功能有效,哪些无效。或者你可以让https://www.ssllabs.com/ssltest/ 做他们的罐头但相当彻底的测试。

错误条目说您可以设置 sysprop jdk.tls.client.protocols,这适用于我在 8u05 上的最小 SSLSocket(不是 HTTP)应用程序中。或者由于您已经在修改 SSLSocketFactory,我希望您可以在您创建的套接字上执行 setEnabledProtocols

FWIW,当 OpenSSL 在 2012 年 3 月发布 1.0.1 时“默默地”开启了协议 1.1 和 1.2(它在发行说明中很突出,但几乎没有人阅读发行说明),支持列表收到了很多抱怨,我d 猜测总共有一百多个服务器突然开始出现故障、崩溃或挂起,直到客户端恢复到 1.0。 OpenSSL 最终实现了一种变通方法,可以人为地减少或增加 ClientHello 中的一些数据,以避免最“挑衅”的大小;我不知道 JSSE 是否可以做类似的事情。

【讨论】:

  • 这个,就是这个!我不敢相信我没有注意到我自己的 ssl 调试跟踪输出中的版本差异!我们能够按照您的建议和执行以下操作:“setEnabledProtocols(“TLSv1”);”目前我们将使用它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多