java https 请求 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

简介: java https 请求 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

最近联调https接口时,请求https 一直报handshake_failure 握手失败。在网上百度了几天,验证了很多方法,一直没有解决我的问题。

我把我的解决方法,分析一下,供大家参考

http-nio-8084-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

HTTPS 专用检测工具网站

https://myssl.com/

HTTPS 安全评估、ATS 检测、证书链补全工具、HTTP/2 支持检测

解决方法1:设置https.protocols

System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");

设置输出网络日志

System.setProperty("javax.net.debug", "all");

然后看到下面的输出:

0000: 16 03 03 00 89 01 00 00 85 03 03 5F 6A C2 08 7C ..........._j...
0010: A9 2A 33 9A C9 B7 D2 11 CA A4 49 2F CD CB 74 14 .*3.......I/..t.
0020: 09 BB 6F 4B 0C 7A 81 82 62 D1 7A 00 00 26 00 3D ..oK.z..b.z..&.=
0030: 00 6B 00 6A 00 35 00 39 00 38 00 3C 00 67 00 40 .k.j.5.9.8.<.g.@
0040: 00 2F 00 33 00 32 00 9D 00 9F 00 A3 00 9C 00 9E ./.3.2..........
0050: 00 A2 00 FF 01 00 00 36 00 0D 00 1C 00 1A 06 03 .......6........
0060: 06 01 05 03 05 01 04 03 04 01 04 02 03 03 03 01 ................
0070: 03 02 02 03 02 01 02 02 00 00 00 12 00 10 00 00 ................
0080: 0D 61 70 69 2E 39 39 35 31 32 30 2E 63 6E .api.995120.cn

0000: 15 03 03 00 02 .....

0000: 02 28 .(
http-nio-8084-exec-1, READ: TLSv1.2 Alert, length = 2
http-nio-8084-exec-1, RECV TLSv1.2 ALERT: fatal, handshake_failure
http-nio-8084-exec-1, called closeSocket()
http-nio-8084-exec-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1950)
at sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:1945)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1944)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1514)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
at com.hipee.web.hour24ecg.controller.TestController.saveBinary(TestController.java:39)
at com.hipee.web.hour24ecg.controller.TestController.versionInfo(TestController.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

解决方法2:替换JCE包
因为我的服务器是jdk8版本,下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt,
替换${java_home}/jre/lib/security/ 下面的local_policy.jar和US_export_policy.jar即可
JDK7: https://www.jianshu.com/go-wild?ac=2&url=https%3A%2F%2Fwww.oracle.com%2Ftechnetwork%2Fjava%2Fjavase%2Fdownloads%2Fjce-7-download-432124.html
JDK8: https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
但我的jdk版本格式如上

[developer@143-196 security]$ pwd

/usr/java/jdk1.8.0_231/jre/lib/security
[developer@143-196 security]$ ll
total 160
-rw-r--r-- 1 10 143 4054 Oct 5 2019 blacklist
-rw-r--r-- 1 10 143 1273 Oct 5 2019 blacklisted.certs
-rw-r--r-- 1 10 143 100515 Oct 5 2019 cacerts
-rw-r--r-- 1 10 143 2466 Oct 5 2019 java.policy
-rw-r--r-- 1 10 143 44261 Oct 5 2019 java.security
-rw-r--r-- 1 10 143 98 Oct 5 2019 javaws.policy
drwxr-xr-x 4 10 143 38 Oct 5 2019 policy
-rw-r--r-- 1 10 143 0 Oct 5 2019 trusted.libraries
[developer@143-196 security]$ tree policy/
policy/
├── limited
│   ├── local_policy.jar
│   └── US_export_policy.jar
└── unlimited

├── local_policy.jar
└── US_export_policy.jar

因为从Java 1.8.0_151版本开始,java公司为JVM启用无限制强度管辖策略,则不能使用AES-256。把java.security文件的第826行的注释去掉即可

crypto.policy=unlimited

重新启动项目,还是失败
linux服务器错误日志:

keyStore is :

keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
http-nio-8084-exec-1, setSoTimeout(0) called
http-nio-8084-exec-1, the previous server name in SNI (type=host_name (0), value=api.995120.cn) was replaced with (type=host_name (0), value=api.995120.cn)
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session

win本地环境正常日志

Allow unsafe renegotiation: true

Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
qtp1971495275-19, setSoTimeout(0) called
qtp1971495275-19, the previous server name in SNI (type=host_name (0), value=api.995120.cn) was replaced with (type=host_name (0), value=api.995120.cn)
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1

发现确实*SHA384

解决方法3:BouncyCastle配置
BouncyCastle是一款开源的密码包,其中包含了大量的密码算法,使用BouncyCastle的目的就是为了扩充算法支持
(1) 将bcprov-jdk15on-162.jar文件导入相关工程
(2) 在需要使用加密的代码中导入以下两个类

import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

(3) 在初始化密钥工厂、密钥生成器等引擎前调用如下代码:
加入BouncyCastleProvider的支持

Security.add.addProvider(new BouncyCastleProviderrr());

或者使用以下方式

MessageDigest md = MessageDigest.getInstant("MD4","BC");

//每个提供者都有简称,Bouncy Castle提供者的简称为BC

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.66</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-ext-jdk15on</artifactId>
        <version>1.66</version>
    </dependency>

最终解决

相关文章
|
3月前
|
网络安全 API CDN
如何将Cloudflare HTTPS的SSL证书更换为Google签发的
将Cloudflare HTTPS的SSL证书更换为Google签发的
|
5月前
|
数据采集 安全 网络安全
使用aiohttp实现异步HTTPS爬虫的SSL优化
使用aiohttp实现异步HTTPS爬虫的SSL优化
282 81
|
8月前
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
|
5月前
|
数据采集 自然语言处理 Java
Playwright 多语言一体化——Python/Java/.NET 全栈采集实战
本文以反面教材形式,剖析了在使用 Playwright 爬取懂车帝车友圈问答数据时常见的配置错误(如未设置代理、Cookie 和 User-Agent),并提供了 Python、Java 和 .NET 三种语言的修复代码示例。通过错误示例 → 问题剖析 → 修复过程 → 总结教训的完整流程,帮助读者掌握如何正确配置爬虫代理及其它必要参数,避免 IP 封禁和反爬检测,实现高效数据采集与分析。
248 3
Playwright 多语言一体化——Python/Java/.NET 全栈采集实战
|
5月前
|
Go
在golang中发起http请求以获取访问域名的ip地址实例(使用net, httptrace库)
这只是追踪我们的行程的简单方法,不过希望你跟着探险家的脚步,即使是在互联网的隧道中,也可以找到你想去的地方。接下来就是你的探险之旅了,祝你好运!
189 26
|
5月前
|
JSON 安全 网络协议
HTTP/HTTPS协议(请求响应模型、状态码)
本文简要介绍了HTTP与HTTPS协议的基础知识。HTTP是一种无状态的超文本传输协议,基于TCP/IP,常用80端口,通过请求-响应模型实现客户端与服务器间的通信;HTTPS为HTTP的安全版本,基于SSL/TLS加密技术,使用443端口,确保数据传输的安全性。文中还详细描述了HTTP请求方法(如GET、POST)、请求与响应头字段、状态码分类及意义,并对比了两者在请求-响应模型中的安全性差异。
427 20
|
6月前
|
数据采集 自然语言处理 JavaScript
Playwright多语言生态:跨Python/Java/.NET的统一采集方案
随着数据采集需求的增加,传统爬虫工具如Selenium、Jsoup等因语言割裂、JS渲染困难及代理兼容性差等问题,难以满足现代网站抓取需求。微软推出的Playwright框架,凭借多语言支持(Python/Java/.NET/Node.js)、统一API接口和优异的JS兼容性,解决了跨语言协作、动态页面解析和身份伪装等痛点。其性能优于Selenium与Puppeteer,在学术数据库(如Scopus)抓取中表现出色。行业应用广泛,涵盖高校科研、大型数据公司及AI初创团队,助力构建高效稳定的爬虫系统。
293 2
Playwright多语言生态:跨Python/Java/.NET的统一采集方案
|
6月前
|
安全 网络安全 数据安全/隐私保护
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
300 3
|
9月前
|
网络协议 算法 数据建模
IP 地址,包括 IPv6 怎么申请 SSL证书来实现 https
很多企业单位已经开始在使用 IPv6 资源,跟 IPv4 一样,IPv6也是需要SSL证书的。在目前的SSL证书品牌,KeepTrust 是可以支持 IPv6 地址的。跟普通IP地址一样,给IPv6签发SSL证书也是需要验证申请者对 IP 地址的管理权限的。如果是 OV 版,还需要验证组织信息的真实性。
|
8月前
|
安全 网络安全 数据安全/隐私保护
HTTPS与SSL证书的关系
**HTTPS 与 SSL 证书:安全通信的基石** 在互联网时代,网络安全至关重要。HTTPS 和 SSL 证书是保障网站安全通信的关键。HTTPS 是 HTTP 的安全版本,通过 SSL/TLS 协议加密数据,防止窃取和篡改。SSL 证书用于验证网站身份并加密通信,包含域名、CA、公钥等信息。两者共同确保数据加密、身份验证,提升用户信任度,并有助于 SEO 优化。部署 HTTPS 和 SSL 证书是提升网站安全性和用户体验的必要措施。

热门文章

最新文章