当前位置: 首页 > news >正文

【报错解决】Java 连接https报错「javax.net.ssl.SSLHandshakeException」怎么破?看这篇!

目录

  • javax.net.ssl.SSLHandshakeException 错误解析与解决方案
    • 错误分析
    • 解决方案
      • 1. 临时解决方案:禁用证书验证(不推荐生产环境)
      • 2. 正确方案:导入服务器证书到Java信任库
        • 步骤1:导出服务器证书
        • 步骤2:导入证书到Java信任库
      • 3. 使用自定义信任库(不修改系统证书)
        • 步骤1:创建自定义信任库
        • 步骤2:在应用中指定自定义信任库
      • 4. 应用程序启动参数配置
    • 验证方法
    • 常见错误原因排查

javax.net.ssl.SSLHandshakeException 错误解析与解决方案

错误分析

这个错误通常在Java应用程序连接HTTPS服务时出现,核心问题是证书链验证失败。错误堆栈显示:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

错误原因

  • 访问的地址用的自签名证书
  • Java信任库中缺少服务器证书的根CA证书
  • 服务器证书过期或域名不匹配
  • 证书链不完整(缺少中间证书)
  • 自定义信任库配置错误

解决方案

1. 临时解决方案:禁用证书验证(不推荐生产环境)

创建信任所有证书的SSLContext:

import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.net.URL;public class TrustAllCerts {public static void main(String[] args) throws Exception {// 创建信任所有证书的TrustManagerTrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {public X509Certificate[] getAcceptedIssuers() { return null; }public void checkClientTrusted(X509Certificate[] certs, String authType) {}public void checkServerTrusted(X509Certificate[] certs, String authType) {}}};// 安装信任管理器SSLContext sc = SSLContext.getInstance("SSL");sc.init(null, trustAllCerts, new java.security.SecureRandom());HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());// 创建允许所有主机名的主机名验证器HostnameVerifier allHostsValid = (hostname, session) -> true;HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);// 测试连接URL url = new URL("https://your-server.com");HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();conn.connect();System.out.println("连接成功(已禁用证书验证)");}
}

2. 正确方案:导入服务器证书到Java信任库

步骤1:导出服务器证书
# 使用OpenSSL导出证书
echo -n | openssl s_client -connect your-server.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > server.crt# 或使用keytool(需要先访问一次服务器)
keytool -exportcert -rfc -alias your-server -keystore ~/.keystore -file server.crt
步骤2:导入证书到Java信任库
# 查找JRE位置
echo $JAVA_HOME# 导入证书
keytool -import -alias your-server -file server.crt -keystore $JAVA_HOME/jre/lib/security/cacerts# 默认密码为changeit

3. 使用自定义信任库(不修改系统证书)

步骤1:创建自定义信任库
# 创建新的信任库
keytool -import -alias your-server -file server.crt -keystore custom-truststore.jks# 设置密码(如mypassword)
步骤2:在应用中指定自定义信任库
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.security.KeyStore;public class CustomTrustStore {public static void main(String[] args) throws Exception {// 加载自定义信任库String trustStorePath = "/path/to/custom-truststore.jks";String trustStorePassword = "mypassword";KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());trustStore.load(new FileInputStream(trustStorePath), trustStorePassword.toCharArray());// 初始化TrustManagerFactoryTrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());tmf.init(trustStore);// 创建SSLContextSSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(null, tmf.getTrustManagers(), null);// 设置默认SSLContextSSLContext.setDefault(sslContext);// 测试连接URL url = new URL("https://your-server.com");HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();conn.connect();System.out.println("连接成功(使用自定义信任库)");}
}

4. 应用程序启动参数配置

在Java应用启动时指定信任库:

java -Djavax.net.ssl.trustStore=/path/to/custom-truststore.jks \-Djavax.net.ssl.trustStorePassword=mypassword \YourMainClass

验证方法

  1. 检查证书是否正确导入
keytool -list -keystore custom-truststore.jks -storepass mypassword
  1. 启用SSL调试日志
java -Djavax.net.debug=ssl:handshake YourMainClass

日志中应包含:

found certificate in keystore

常见错误原因排查

  1. 证书链不完整

    • 使用openssl s_client检查服务器证书链
    • 确保同时导入根证书和中间证书
  2. 证书域名不匹配

    • 使用openssl x509 -noout -subject -in server.crt检查证书域名
    • 确认访问的域名与证书域名一致
  3. 证书过期

    • 使用openssl x509 -noout -dates -in server.crt检查有效期
  4. 多个Java版本冲突

    • 确保导入证书到应用实际使用的JRE中
    • 使用java -version确认当前使用的JRE版本

通过以上方法,可以解决Java应用中SSL握手失败的问题,确保HTTPS连接安全可靠。


文章转载自:

http://dUePjOxM.fcwxs.cn
http://8EgCZNIW.fcwxs.cn
http://RXaIC53Q.fcwxs.cn
http://zSBLGEM5.fcwxs.cn
http://pKFnbiqa.fcwxs.cn
http://PNr7zPPZ.fcwxs.cn
http://AT9NYqrr.fcwxs.cn
http://W2qiA5Wd.fcwxs.cn
http://6MrL28oO.fcwxs.cn
http://mv2llC9b.fcwxs.cn
http://fmQvo5gZ.fcwxs.cn
http://KaJHhlU0.fcwxs.cn
http://d2lNR99f.fcwxs.cn
http://tbxMIiMi.fcwxs.cn
http://FVwWNFL6.fcwxs.cn
http://LpHdMRqA.fcwxs.cn
http://CTLACNLr.fcwxs.cn
http://uvtFGnuY.fcwxs.cn
http://RrZuMgkn.fcwxs.cn
http://ikl8R3VL.fcwxs.cn
http://OuAi5JkS.fcwxs.cn
http://x5hwejdf.fcwxs.cn
http://RcLWhNxw.fcwxs.cn
http://CZMianP9.fcwxs.cn
http://2dKWTGkc.fcwxs.cn
http://qgdy3FE8.fcwxs.cn
http://MLEHffN6.fcwxs.cn
http://2v1Pqt0x.fcwxs.cn
http://A7kFuE6K.fcwxs.cn
http://EXw0J7cc.fcwxs.cn
http://www.dtcms.com/a/247926.html

相关文章:

  • Nginx 配置 HTTPS 与证书格式全解析:支持后端代理验证
  • 使用特征线法求解一阶线性齐次偏微分方程组
  • Android binder内核漏洞研究(一)——环境搭建
  • Eslint、Prettier、.vscode 配置
  • JSON 编辑器:从语法到数据处理(二)
  • 深入 Java 泛型:基础应用与实战技巧
  • 前端构建工具Webapck、Vite——>前沿字节开源Rspack详解——2023D2大会
  • 【JVM】- 类加载与字节码结构2
  • shell、bash、cmd、git 和 PowerShell 的区别与关系的详细解析
  • Qt的Modbus协议-RTU从站实现
  • 泰国零售巨头 CJ Express 借助 SAP 内存数据库实现高效数据管理
  • Qt背景平铺
  • AQS独占模式——资源获取和释放源码分析
  • 泰国数码电商系统定制|3C产品详情泰语化+售后管理,适配泰国数码零售
  • 串口输出版UART接收中断程序 (8259端口400H/402H)
  • 韦东奕论文解读
  • 开发者视角:一键拉起功能解析
  • 1.14 express小项目 和 用到的 jwt详解
  • Java并发进阶系列:深度讨论高并发跳表数据结构ConcurrentSkipListMap的源代码实现(上)
  • 磁盘配额管理
  • Git分页器和Node.js常见问题解决方式
  • 为何京东与蚂蚁集团竞相申请稳定币牌照?
  • 1.13使用 Node.js 操作 SQLite
  • 英飞凌亮相SEMICON China 2025:以SiC、GaN技术引领低碳化与数字化未来
  • 【Google Chrome】谷歌浏览器历史版本下载
  • 容器的本质是进程
  • React第六十二节 Router中 createStaticRouter 的使用详解
  • 仪表刻度动态显示控件--小三角指针
  • YOLOV11改进之多尺度扩张残差模块(MS-DRM)
  • 【论文写作参考文献地址】