sun.security.validator.ValidatorException:PKIX 路径构建失败
Posted
技术标签:
【中文标题】sun.security.validator.ValidatorException:PKIX 路径构建失败【英文标题】:sun.security.validator.ValidatorException: PKIX path building failed 【发布时间】:2014-09-05 06:19:46 【问题描述】:我已使用此命令创建了 CSR 请求:
openssl req -out certificatecsr.csr -new -newkey rsa:2048 -keyout certificatekey.key
在 CA 与我共享证书 (.cer) 文件之后。
现在我已经使用密钥将 .cer 文件转换为 .p12。
使用 CA 发送的 cer 和私钥创建 .p12 证书
C:\Java\jdk1.6.0_38\jre\bin>openssl pkcs12 -export -in C:\Users\asharma1\cert.cer -inkey certificatekey.key -out
certi.p12
创建 JKS 密钥库:
keytool -genkey -alias quid -keystore quid.jks
将 .p12 证书导入 jks 密钥库
C:\Java\jdk1.6.0_38\jre\bin>keytool -v -importkeystore -srckeystore C:\OpenSSL-Win64\bin\certi.p12 -srcstoretype PKCS12
-destkeystore quid.jks -deststoretype JKS
但是当我从我的 java 代码中引用这个 JKS 时,我收到了这个错误:
:
sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效证书路径
我也将 cer 文件添加到 cacerts。但仍然出现相同的错误。
就 JAVA 代码而言,我引用此链接来引用我自己创建的密钥库:
http://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/
public SSLContext getSSLContext(String tspath)
throws Exception
TrustManager[] trustManagers = new TrustManager[]
new ReloadableX509TrustManager(tspath)
;
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, null);
return sslContext;
SSLContext sslContext=getSSLContext("C:\\Java\\jdk1.6.0_38\\jre\\bin\\quid.jks");
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
URL pickUrl = new URL(pickupLocation);
URLConnection urlConn = pickUrl.openConnection();
HttpsURLConnection httpsURLConn = (HttpsURLConnection)urlConn;
httpsURLConn.setSSLSocketFactory(socketFactory);
String encoding = urlConn.getContentEncoding();
InputStream is = urlConn.getInputStream();
InputStreamReader streamReader = new InputStreamReader(is, encoding != null
? encoding : "UTF-8");
请注意我没有使用任何服务器。我正在尝试仅通过 main 方法在编写的代码之上运行。
请告诉我需要做什么。 为什么我需要将我的 .cer 文件转换为 .p12 文件?
【问题讨论】:
这没有任何意义。您必须首先生成私钥。 然后是 CSR。然后签到。然后将其与私钥重新组合。 @EJP 命令openssl req -out certificatecsr.csr -new -newkey rsa:2048 -keyout certificatekey.key
根据文档here 创建一个新的证书请求和一个新的私钥
那么你究竟为什么要使用'keytool -genkey'?
@EJP 这正是正在发生的事情。首先生成私钥和 csr,然后由 CA 签名,然后将其与私钥组合形成 .p12 密钥库。然后将其转换为 JKS 存储。
没有。 'keytool -genkey' 创建一个 new 密钥。请参阅文档。您的命令序列没有意义。
【参考方案1】:
我建议您将 CA 证书(或整个 CA 链和中间 CA)导入密钥库。
我认为 p12 导入得很好。我的建议是将链导入密钥库。至少这是错误消息所说的。
我认为:
链中的根 CA 不受信任,因此链构建失败或 链中的证书中没有 AIA 部分,因此无法获取到受信任的根 CA 的证书,因此链构建失败或 没有基于 AIA 获取证书,因为它没有在 java 中实现(我不是 java 程序员)所以链构建失败您可以使用portecle 导入缺少的受信任 CA 证书(不是您在 .p12 或您从颁发 CA 收到的单独 .cer 文件中拥有的最终实体证书)。它比 keytool 更加用户友好。只需关注此guide。
【讨论】:
感谢您的回复,我已经使用 portecle 进行了检查。证书存在于 quid.jks 密钥库中。我已经检查了 quid.jks 中的 .cer 和 .p12 文件但是,当我尝试通过 portecle 导入受信任的证书(certi.p12)时,它显示错误“在 certi.p12 中找不到证书”,但适用于 . .cer 文件。我不确定根 CA 和中间 CA。需要检查什么?我猜导入证书相当于导入CA。【参考方案2】:我建议您使用 *.der 格式而不是 .p12 格式。
以下是如何导入证书以修复以下错误的总体摘要:
尝试执行请求时出错。 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:PKIX 路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException:无法 找到请求目标的有效认证路径
如何导入证书
-
在浏览器中转到 URL,点击 HTTPS 证书链(URL 地址旁边的小锁符号)导出证书
点击“更多信息”>“安全”>“显示证书”>“详细信息”>“导出..”。
另存为
.der
对需要导入的任何证书重复此操作
找到 $JAVA_HOME/jre/lib/security/cacerts
使用以下命令将所有 *.der 文件导入 cacerts 文件:
sudo keytool -import -alias mysitestaging -keystore $JAVA_HOME/jre/lib/security/cacerts -file staging.der
sudo keytool -import -alias mysiteprod -keystore $JAVA_HOME/jre/lib/security/cacerts -file prod.der
sudo keytool -import -alias mysitedev -keystore $JAVA_HOME/jre/lib/security/cacerts -file dev.der
默认密钥库密码是“changeit”
您可以查看您使用此显示证书指纹的命令所做的更改。
keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts
如果这不能解决问题,请尝试添加这些 java 选项作为参数:
-Djavax.net.ssl.trustStore="$JAVA_HOME/jre/lib/security/cacerts"
-Djavax.net.ssl.trustStorePassword="changeit"
【讨论】:
以上是关于sun.security.validator.ValidatorException:PKIX 路径构建失败的主要内容,如果未能解决你的问题,请参考以下文章