调用https接口抛出javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path

在调用HTTPS接口时遇到 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path 错误。通过创建自定义的https协议类MySSLSocketFactory,并在请求中使用,成功解决了本地调通但部署后无法调通的问题。

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

问题:

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 
       

前几日,本小白在工作的时候,做到一个需求,就是请求一个https的接口,但是呢碰到一个很奇怪的问题就是,我本地可以完美调通,但是提交代码后没有一个能调通。。。。在网上找了一圈都不好使,最后找到这样的一个方法,直接上硬菜。

解决方法:

1,先搞一个 自己的https协议类 MySSLSocketFactory.java

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

public class MySSLSocketFactory implements ProtocolSocketFactory {
    static {
        System.out.println(">>>>in MySSLSocketFactory>>");
    }
    private SSLContext sslcontext = null;

    private SSLContext createSSLContext() {
        SSLContext sslcontext = null;
        
### 解决方案概述 `javax.net.ssl.SSLHandshakeException: PKIX path building failed` 错误通常发生在Java应用程序尝试通过SSL/TLS协议建立安全连接时,但由于无法验证服务器的证书链而导致握手失败。以下是详细的解决方案。 --- #### 方法一:导入正确的CA证书到信任库 如果问题是由于缺少有效的根证书或中间证书引起的,则可以通过将这些证书手动导入到Java的信任库中解决问题。操作步骤如下: 1. **下载所需的证书** 使用浏览器访问目标URL并导出其使用的SSL证书(通常是PEM格式)。或者可以使用命令行工具提取证书: ```bash echo | openssl s_client -showcerts -connect example.com:443 2>/dev/null | openssl x509 -outform PEM > certificate.pem ``` 2. **导入证书至Java KeyStore (JKS)** Java默认的信任库文件位于 `$JAVA_HOME/lib/security/cacerts` 或 `jssecacerts` 中。可以使用 `keytool` 命令将其导入: ```bash keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/jssecacerts -storepass changeit -alias myAlias -file certificate.pem ``` 如果不存在 `jssecacerts` 文件,也可以直接导入到 `cacerts`。 3. **设置环境变量** 确保运行程序时指定新的KeyStore位置: ```java System.setProperty("javax.net.ssl.trustStore", "$JAVA_HOME/jre/lib/security/jssecacerts"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); ``` 此方法适用于需要长期维护的安全连接场景[^2]。 --- #### 方法二:禁用主机名验证(仅用于测试) 对于开发阶段或临时调试需求,可以选择跳过SSL验证逻辑。但这并不推荐用于生产环境中,因为会降低安全性。 实现方式之一是自定义 `TrustManager` 和 `HostnameVerifier` 类忽略所有证书校验: ```java import javax.net.ssl.*; import java.security.cert.X509Certificate; public class SSLUtil { public static void disableSSLCertCheck() throws Exception { TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {} @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; HostnameVerifier allHostsValid = (hostname, session) -> true; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } } ``` 调用该函数即可关闭SSL认证过程中的严格检查机制[^4]。 注意这种方法存在安全隐患,在正式部署前应移除此类代码片段。 --- #### 方法三:更新JDK版本 某些旧版JDK可能未包含最新的受信根证书列表,从而引发PKIX路径构建失败问题。建议升级至最新稳定发行版以获取更全面的支持[^3]。 例如从Oracle官网下载安装最新一代OpenJDK/JRE包,并重新配置项目依赖项指向新版本。 --- ### 总结说明 以上三种途径分别针对不同层次的原因提供了应对策略——即补充缺失凭证、绕开现有约束以及优化基础架构支持能力。实际应用过程中需依据具体情况权衡利弊选取最合适的处理办法。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值