【BugFix】https 握手失败 SSLHandshakeException handshake

mac2025-10-18  7

1.现象

客户端httpclient访问https服务端,抛出javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

2.原因

JDK1.8版本不支持服务端要求的加密算法套件当加密密钥长度>128

2.1排查过程

由于客户端做了永久信任,服务端也要求单向认证,所以一定不是证书问题。

服务端要求TLS1.2、TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384套件

后来发现服务端指定了一个算法套件,抓包tcpdump+Wireshark发现客户端发送的client hello算法套件 不包含服务端要求的TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

服务端响应包:

Secure Sockets Layer

TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)

服务端要求的是TLS1.2 ,协议版本没有问题,那就应该是加密算法套件的问题

查看本地JRE和服务端支持的加密套件,可用openssl来获取服务端

openssl s_client -connect serverxxx:443

得到一下信息,省略无关信息

SSL-Session:     Protocol  : TLSv1.2     Cipher    : AES256-GCM-SHA384  

服务器确实需要AES256-GCM-SHA384,这是一个很长长度的强加密,一般128位长度加密就够了

对Java代码也来一次调试,确认它所支持的所有加密套件。

-Dssl.debug=true -Djavax.net.debug=all

返回结果确实如此,根本就不存在基于AES256-GCM-SHA384的加密方法。

问题在于发行的JDK1.8版本JRE本身仅支持长度128的弱加密,它默认做了很多加密长度限制的裁剪,就是只出口强度低的加密,这是美国政府对于安全软件的强制性规定。

解决方法

但Oracle允许下载强加密的未限制版本,可去官网下载一个压缩包叫做 “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8”。对于JDK1.8版本但是低于1.8.0_151版本的JDK,将下载的包里的两个文件直接覆盖到本地 Java\jre\lib\security\

local_policy.jar

US_export_policy.jar

1.8.0_151和以后的版本,只要修改Java\jre\lib\security\java.security文件,修改这一行注释并启用就可以了。

crypto.policy=unlimited

 

最新回复(0)