对于javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure错误某一情况的处理

对于javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure错误某一种情况的处理

一般出现 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 错误看名字就是握手的时候发生问题(废话)可能原因也以下几点:

  1. 客户端和服务器支持的SSL/TLS版本不兼容。
  2. 客户端支持的加密套件列表与服务器不匹配。
  3. 服务器的SSL证书可能不可信或已过期。
  4. 客户端的安全套件配置错误或不正确。

首先在网络请求时候打开日志:

System.setProperty("javax.net.debug", "ssl:handshake");

然后对比到底是哪部分出现错误;
我这里遇见的是加密套件不匹配:(请看一段简单网络请求代码)

HttpClient httpClient = null;
try {
	//System.setProperty("javax.net.debug", "all"); 
    System.setProperty("javax.net.debug", "ssl:handshake"); //开启ssl日志
    System.setProperty("jdk.internal.httpclient.disableHostnameVerification","true");//取消主机名验证
    SSLParameters sslParameters = new SSLParameters();
    //sslParameters.setProtocols(new String[]{ "TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3", "SSLv2Hello" });
    SSLContext sslContext = SSLContext.getInstance("TLS");
    //忽略证书验证
    sslContext.init(null, new TrustManager[]{ new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
        @Override
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0];}
    }}, null);
    httpClient = HttpClient.newBuilder()
            .sslParameters(sslParameters)
            .sslContext(new SSLHelper().sslContext())
            .followRedirects(HttpClient.Redirect.NORMAL)
            .build();
    String str = "请求地址";
    var request = HttpRequest.newBuilder().GET().uri(new URI(str))
            .header("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.46")
            .header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
            .build();
    HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder().GET().uri(new URI(str)).build(),
            HttpResponse.BodyHandlers.ofString());
    System.err.println(response);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(httpClient != null) httpClient.close();
}

出现的异常:(部分展示)

javax.net.ssl|DEBUG|02|HttpClient-1-Worker-0|2024-08-29 15:30:58.921 CST|ClientHello.java:640|Produced ClientHello handshake message (
"ClientHello": {
  "client version"      : "TLSv1.2",
  "random"              : "2465D4171866802D69373DAE605B1835AA835105305A214D301D5D85D4253442",
  "session id"          : "E6AA3EECCE23680853EFAC383D83B7BFFCA8571A40BB82B1F3A5F22189117EED",
  "cipher suites"       : "[TLS_AES_256_GCM_SHA384(0x1302), TLS_AES_128_GCM_SHA256(0x1301), ...
  ...
}
...
...
javax.net.ssl|DEBUG|02|HttpClient-1-Worker-0|2024-08-29 15:30:59.000 CST|ServerHello.java:883|Consuming ServerHello handshake message (
"ServerHello": {
  "server version"      : "TLSv1.2",
  "random"              : "F79E21C1219933F82DD6353C907BAF05853450DA6C2AE01775177F595DACA139",
  "session id"          : "",
  "cipher suite"        : "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030)",
  "compression methods" : "00",
  ...
}
...
...
javax.net.ssl|DEBUG|02|HttpClient-1-Worker-0|2024-08-29 15:30:59.023 CST|CertificateMessage.java:360|Consuming server Certificate handshake message (
"Certificates": [
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "201501527BDE42E4F886C2B545AFC937",
    "signature algorithm": "SHA256withRSA",
    "issuer"             : "CN=***, O=***, C=CN",
    "not before"         : "2024-03-24 14:25:07.000 CST",
    "not  after"         : "2025-01-27 16:31:11.000 CST",
    "subject"            : "CN=******",
    "subject public key" : "RSA",
    ...
}
...
...
javax.net.ssl|DEBUG|02|HttpClient-1-Worker-0|2024-08-29 15:30:59.088 CST|Alert.java:232|Received alert message (
"Alert": {
  "level"      : "fatal",
  "description": "handshake_failure"
}
...
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:956)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133)
at network.LocalNetworkTest.main(LocalNetworkTest.java:50)
...

(不了解日志的同学可以先看看这位大佬写的:SSL/TLS 握手过程详解

从异常信息里面看出,协议没问题,证书签名处挂了!密码套件没匹配上!
看出来对方使用的 SHA256withRSA 加密,我们客户端也要加上相印的加密套件才行
(把下面代码加在上面示例中相应位置即可)

sslParameters.setCipherSuites(new String[]{ "TLS_RSA_WITH_AES_256_CBC_SHA256" });

再次请求:OK!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

行真爸爸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值