Received fatal alert: handshake_failure

背景

从后端请求第三方的提供的https接口,一直提示握手失败javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure,但api放到浏览器直接访问是没问题的,这也证明了人家提供的api可用性。

我发起请求的客户端是jdk8版本,我试着请求其他平台https接口,能获取到数据,又证明了我代码是没问题了。那问题出在哪?

分析

我在本地的IDEA打开SSL的debug调试,在jvm启动加入 

-Djavax.net.debug=all

发起一个请求,携带版本号,加密套件列表,发起第一次握手

 按正常流程,服务器端应该给我回礼Hello,但在日志中却看到握手失败的提示

 这说明服务器那边验证没通过,直接拒绝了本次握手,我们打开分析工具亚数信息-SSL/TLS安全评估报告,分析下请求的域名

在 Java 中,当出现 `Received fatal alert: handshake_failure` 错误时,若要忽略证书验证,可按如下步骤操作。 首先,创建一个自定义的 `TrustManager` 类,该类会信任所有证书: ```java import javax.net.ssl.X509TrustManager; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class TrustAllManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // 不做任何验证,信任所有客户端证书 } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // 不做任何验证,信任所有服务器证书 } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } ``` 接着,创建一个自定义的 `HostnameVerifier` 类,该类会验证所有主机名: ```java import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; public class TrustAllHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return true; // 信任所有主机名 } } ``` 然后,在代码里设置 `SSLContext` 和 `HostnameVerifier`: ```java import javax.net.ssl.*; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; public class SSLUtils { public static void trustAllCertificates() throws NoSuchAlgorithmException, KeyManagementException { // 创建一个信任所有证书的 TrustManager TrustManager[] trustAllCerts = new TrustManager[]{new TrustAllManager()}; // 获取 SSLContext 实例 SSLContext sc = SSLContext.getInstance("SSL"); // 初始化 SSLContext sc.init(null, trustAllCerts, new SecureRandom()); // 设置默认的 SSLSocketFactory HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // 设置默认的 HostnameVerifier HttpsURLConnection.setDefaultHostnameVerifier(new TrustAllHostnameVerifier()); } } ``` 最后,在发起网络请求前调用 `trustAllCertificates` 方法: ```java import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; public class Main { public static void main(String[] args) { try { // 调用信任所有证书的方法 SSLUtils.trustAllCertificates(); // 创建 URL 对象 URL url = new URL("https://your-url-here"); // 打开连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 处理响应 // ... } catch (NoSuchAlgorithmException | KeyManagementException | IOException e) { e.printStackTrace(); } } } ``` 通过以上步骤,就能在出现 `Received fatal alert: handshake_failure` 错误时忽略证书验证。不过要注意,在生产环境中忽略证书验证存在安全风险,可能会遭受中间人攻击,所以仅建议在开发和测试环境使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_深巷的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值