HTTPS握手异常:Received fatal alert: handshake_failure

问题

  项目中使用第三方支付:通联支付,来实现扫码支付功能,使用HTTPS进行通信。本地开发测试没有问题,可是将项目打包发布到客户服务器,支付请求一直报:Received fatal alert: handshake_failure

具体信息如下所示:

>

Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)


分析

  Received fatal alert: handshake_failure直接翻译是”HTTPS接收阶段发生了致命错误”。
  后来仔细查看了,项目启动控制台日志:

main, WRITE: TLSv1 Handshake, length = 75
main, WRITE: SSLv2 client hello message, length = 101
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure

  所以我发现了问题。在低版本Java的JDK中可能存在一个bug:客户机似乎启动了一个TLSv1握手,但随后发送了一个SSLv2客户端hello消息,此时服务器端发出了一个TLSV1 Alert警告,拒绝握手连接。


解决方案

1.创建SSLContext实例,明确指定使用TLS协议进行处理:
SSLContext sslContext = SSLContext.getInstance("TLS");
2.设置系统属性:
System.setProperty("https.protocols", "TLSv1");


HTTPS协议学习地址

Java 和 HTTP 的那些事(一) 模拟 HTTP 请求

你可能感兴趣的:(日常项目遇到的坑)