解决HttpClient访问https(包括通过http代理)出现unable to find valid certification path to requested target的问题

本文介绍如何解决Java程序通过HTTPS代理访问网站时遇到的证书验证失败问题。通过将代理工具的证书导入JRE证书库,确保Java程序可以正确验证HTTPS连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 知识预备

要理解本文,需要掌握以下知识:

  • https基本原理,包括证书分发和密钥协商等 [1];
  • http代理和https代理的基本原理 [2];
  • 常用的本地http代理工具,如Fiddler, BurpSuite;
  • 懂Java语言,了解HttpClient的基本功能和API [3]。

2. 问题描述与分析

使用httpclient写程序访问https页面,中间需要通过本地的http/https代理,如下所示:
Java程序(基于httpclient) <——-> 代理工具 (如Fiddler) <———> Web服务器
当运行Java程序后,程序出现异常,提示:

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

从错误提示可以看到是无法验证网站的证书,找不到证书验证链。为了解决问题,将代理工具生成的证书作为可信根证书导入系统证书库,但是问题依然存在。在阅读了资料[1]之后才恍然大悟,原来Java的证书验证系统是独立于操作系统和浏览器的,而是使用JRE中证书库,所有必须把代理工具的证书加入到JRE的证书库中。

3. 问题解决

在Windows系统中,JRE证书库路劲为Program Files\Java\jdk1.x.x\jre\lib\security\cacerts。Java使用Keytool管理证书,其路径为Program Files\Java\jdk1.8.0_144\bin\keytool.exe。所以,需要的操作是使用keytool将代理工具的证书加入到cacerts中。在[2]对上述过程有详细的原理解释。打开命令行,进行如下操作:
Step 1. cd到keytool.exe所在目录;
Step 2. 执行下述命令(命令参数说明参考keytool帮助文件)

>keytool -import -alias FIDDLER -keystore ../lib/security/cacerts -file 代理工具证书路径\证书文件名

如果提示输入口令,java默认口令是changeit,最后输入y信任此证书。
Step 3. 确认证书已经被导入可信根证书库

keytool -list -keystore ../lib/security/cacerts

参考资料

[1] Java 和 HTTP 的那些事(四) HTTPS 和 证书
[2] https代理原理
[3] HttpClient 4.5

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值