在Java中使用HTTPS请求证书

时间:2018-05-30 07:12:35

标签: java ssl https pkcs#12

我想通过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中使用这些文件的方式错了吗?

1 个答案:

答案 0 :(得分:0)

PKCS12通常包含私钥和证书(链)组合,用于验证您的系统即客户端,这是使用javax.net.ssl.keyStore*属性完成的。您应该指定类型PKCS12,尽管某些Java8版本(仅!)在您指定JKS时可以读取PKCS12。

它通常不会对javax.net.ssl.trustStore*所用的服务器进行身份验证,因此请不要在那里使用它。根据服务器(s?),您可能需要也可能不需要与P12不同的自定义信任库,也不同于Java的默认信任库。 使用浏览器或其他工具(如curlkeytool -printcert -sslserver host[:port])查看服务器使用的证书链 并确定它是否使用像Verisign-now-Symantec-now-Digicert或GoDaddy这样的公共根CA,它们已经存在于Java的默认信任库中,或者是私有的#en; CA或甚至是自签名证书,在这种情况下,您应该将该证书添加到默认信任库,或者如果您不能或不想修改您的JVM,请将该证书放在您使用的密钥库文件中作为信任商店。

PS:ValidatorException 导致 SSLHandshakeException而不是相反。