You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenJDK 17发送HTTPS请求遇SSLHandshakeException握手失败

解决OpenJDK 17.0.1下SSL握手失败问题

我使用OpenJDK 17.0.1向服务器发送GET请求时,持续收到错误:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure。

实现代码

package org.example;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.security.KeyStore;

public class HttpsGetWithCustomSSLExample {
    public static void main(String[] args) {
        try {
            // 目标API地址
            String apiUrl = "https://192.168.14.193:8050/sample-v1";

            // 加载信任库
            KeyStore trustStore = KeyStore.getInstance("JKS");
            try (FileInputStream trustStoreInputStream = new FileInputStream("store/server.truststore")) {
                trustStore.load(trustStoreInputStream, "WalletPasswd123".toCharArray());
            }

            // 加载密钥库
            KeyStore keyStore = KeyStore.getInstance("JKS");
            try (FileInputStream keyStoreInputStream = new FileInputStream("store/server.keystore")) {
                keyStore.load(keyStoreInputStream, "WalletPasswd123".toCharArray());
            }

            // 创建包含自定义信任库和密钥库的SSL上下文
            SSLContext sslContext = SSLContextBuilder.create()
                    .loadTrustMaterial(trustStore, null)
                    .loadKeyMaterial(keyStore, "WalletPasswd123".toCharArray())
                    .setProtocol("TLSv1.3")
                    .build();

            // 创建带SSL上下文的HttpClient
            CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).build();

            // 创建GET请求
            HttpGet httpGet = new HttpGet(apiUrl);

            // 执行请求并处理响应
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                int responseCode = response.getStatusLine().getStatusCode();
                System.out.println("响应码: " + responseCode);

                String responseBody = EntityUtils.toString(response.getEntity());
                System.out.println("响应内容: " + responseBody);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

错误截图

错误截图


排查与解决方法

  • 检查TLS版本兼容性:代码中强制指定了TLSv1.3,若服务器不支持该版本会直接握手失败。可以尝试:

    • 移除.setProtocol("TLSv1.3"),让JDK自动协商双方支持的最高TLS版本;
    • 改为指定服务器明确支持的版本,比如.setProtocol("TLSv1.2")。
  • 验证密钥库与信任库有效性:

    • 确认store/server.truststore和store/server.keystore文件路径正确,程序可正常读取;
    • 用keytool命令检查证书状态:
      # 查看信任库证书列表
      keytool -list -keystore store/server.truststore -storepass WalletPasswd123
      # 查看密钥库证书列表
      keytool -list -keystore store/server.keystore -storepass WalletPasswd123
      
    • 确保信任库中包含服务器的CA证书,密钥库中的客户端证书已被服务器信任。
  • 检查证书链完整性:服务器证书可能缺少中间证书,导致客户端无法完成验证。需将完整的证书链(根证书+中间证书)导入信任库。

  • 启用SSL调试日志定位问题:添加JVM启动参数-Djavax.net.debug=ssl,handshake,运行程序后查看详细握手日志,可明确是协议协商失败、证书验证失败还是其他环节出问题。


内容的提问来源于stack exchange,提问作者Pasindu Ukwatta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:40:08