java - TLS 1.2 客户端问候失败

标签 java ssl sslhandshakeexception

我有一个 Java 应用程序,用于自动从 NOAA 提取数据。直到本周它在 TLS 握手时突然失败时,它一直运行良好。查看调试跟踪,它在初始客户端 Hello 上收到来自服务器的致命警报:

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1557742545 bytes = { 197, 46, 181, 254, 21, 83, 77, 65, 33, 85, 238, 194, 203, 141, 5, 105, 252, 60, 193, 124, 125, 111, 213, 237, 107, 20, 110, 136 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 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_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 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_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Extension extended_master_secret
***
[write] MD5 and SHA1 hashes:  len = 179
main, WRITE: TLSv1.2 Handshake, length = 179
[Raw write]: length = 184
[Raw read]: length = 5
0000: 15 03 03 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure

我想也许服务器已经改变了它支持的算法,所以我运行了 nmap:

443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: A

因此至少有两个密码套件达成一致。我可以将 Web 浏览器指向我试图读入我的 Java 应用程序的网页,并且工作正常。我确实注意到服务器在上周更换了它的服务器证书,但是我的 Java 应用程序中的 TLS 连接在它到达服务器发送其证书的位置之前就失败了,无论如何,它是服务器那就是中止握手。

我注意到随机 Cookie 中的 GMT 字段应该是客户端的当前时间,但发送的数字有几个月的偏差。不确定这是否是个问题;据我所知,这是我无法控制的,是的,我的系统时钟是正确的。显然服务器不喜欢 Client Hello 中的某些内容,但我无法弄清楚那是什么,但它必须与他们安装的新证书有关。我查看了证书,它由 SHA256 和 SHA1 签名,客户端支持这两种方式。

我不认为这是 Java 编码问题。我认为这是一个配置问题。我正在使用 JRE 1.8.0_231-b11。

网页的网址是:https://ndbc.noaa.gov/data/realtime2/51205.spec

最佳答案

已经有人问过类似的问题。

其实如图SSL Labs您的请求缺少此网站所需的服务器名称扩展。事实上,我们可以在请求中看到其他 4 个扩展,但不是这个。 这停止工作,因为他们更改了服务器配置。 您没有提供客户端的代码,但检查它是否没有使用 -Djsse.enableSNIExtension=false 运行,如 JSSE Reference Guide 中所述。

关于java - TLS 1.2 客户端问候失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59009324/

相关文章:

Java Spring 项目结构 - 未检测到 Controller

.net - 如何将 SMTP 与 c# 4/.NET 4 连接到端口 465/SSL(当前不受支持)...需要想法

java - 使用 IBM JDK 6 启用 ECDHE 密码

c++ - BB10 QNX Momentics IDE 中的 SSL 握手失败

java - Lollipop 握手失败

java - java中的继承和委托(delegate)有什么区别

java - 如何使用Sockets TCP在java和android之间正确传递对象?

java - 如何在内存级别通过类的成员函数访问类的私有(private)成员?

.net - 我修复了一个 TLS 1.2 问题,但我不知道它是如何/为什么工作的,或者它在做什么?这个 Powershell 命令在做什么?

java - 在 JCA 中为 TLS 定义密码套件