我想通过Java中的HTTPS连接调用一些Web服务。证书颁发机构给了我一个PKCS12文件,但我得到了一个
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
由于
javax.net.ssl.SSLHandshakeException
这是我正在执行的代码:
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.keyStore", "path/toto2.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "pwd");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", "path/toto2.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "pwd");
System.setProperty("proxySet","true") ;
System.setProperty("https.proxyHost", "XXX") ;
System.setProperty("https.proxyPort", "XXX") ;
我首先尝试提供PKCS12文件,然后是JKS,但我遇到了同样的错误。
我尝试了另一种解决方案,卷曲。所以我从PKCS12中提取了证书并成功完成了请求。
以下是我用于从P12中提取不同文件的命令:
openssl pkcs12 -in file.p12 -nocerts -nodes -out clientcert.key
openssl pkcs12 -in file.p12 -clcerts -nokeys -out clientcert.cer
openssl pkcs12 -in file.p12 -cacerts -nokeys -chain -out cacerts.cer
我在Java中使用这些文件的方式错了吗?
答案 0 :(得分:0)
PKCS12通常包含私钥和证书(链)组合,用于验证您的系统即客户端,这是使用javax.net.ssl.keyStore*
属性完成的。您应该指定类型PKCS12,尽管某些Java8版本(仅!)在您指定JKS时可以读取PKCS12。
它通常不会对javax.net.ssl.trustStore*
所用的服务器进行身份验证,因此请不要在那里使用它。根据服务器(s?),您可能需要也可能不需要与P12不同的自定义信任库,也不同于Java的默认信任库。
使用浏览器或其他工具(如curl
或keytool -printcert -sslserver host[:port]
)查看服务器使用的证书链
并确定它是否使用像Verisign-now-Symantec-now-Digicert或GoDaddy这样的公共根CA,它们已经存在于Java的默认信任库中,或者是私有的#en; CA或甚至是自签名证书,在这种情况下,您应该将该证书添加到默认信任库,或者如果您不能或不想修改您的JVM,请将该证书放在您使用的密钥库文件中作为信任商店。
PS:ValidatorException
导致 SSLHandshakeException
而不是相反。