简体   繁体   English

在Java中将证书用于HTTPS请求

[英]Use certificate for HTTPS request in Java

I want to call some web services through an HTTPS connection in Java. 我想通过Java中的HTTPS连接来调用某些Web服务。 The certificate authority gave me a PKCS12 file but I get a 证书颁发机构给了我一个PKCS12文件,但我得到了一个

sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

due to 由于

javax.net.ssl.SSLHandshakeException

Here is the code I am executing : 这是我正在执行的代码:

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") ;

I first tried to give the PKCS12 file, then the JKS but I had the same error. 我首先尝试给出PKCS12文件,然后给出JKS,但是我遇到了同样的错误。

I tried another solution, with curl. 我尝试了另一种解决方案,卷曲。 So I extracted certificates from the PKCS12 and the requests successed. 因此,我从PKCS12中提取了证书,请求成功完成。

Here are the commands that I used to extract the different files from the P12 : 这是我用来从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

Am I wrong with the way I use those files in Java ? 我在Java中使用这些文件的方式是否错误?

PKCS12 normally contains a privatekey and cert (chain) combination, and is used to authenticate your system ie the client, which is done with the javax.net.ssl.keyStore* properties. PKCS12通常包含私钥和证书(链)的组合,并用于对系统(即客户端)进行身份验证,这是通过javax.net.ssl.keyStore*属性完成的。 You should specify type PKCS12, although some Java8 versions (only!) can read PKCS12 when you specify JKS. 您应该指定类型PKCS12,尽管指定JKS时某些Java8版本(仅!)可以读取PKCS12。

It typically does NOT authenticate the server(s), which is what javax.net.ssl.trustStore* is for, so don't use it there. 它通常不对服务器进行身份验证,这就是javax.net.ssl.trustStore*的用途,因此不要在那里使用它。 Depending on the server(s?), you may or may not need a custom truststore different from the P12 and also different from Java's default. 根据服务器的不同,您可能需要也可能不需要自定义信任库,该自定义信任库不同于P12,也不同于Java的默认库。 Look at the cert chain used by the server with a browser or other tool like curl or keytool -printcert -sslserver host[:port] and determine whether it uses a public root CA like Verisign-now-Symantec-now-Digicert or GoDaddy, which will already be in Java's default truststore, or a 'private' CA or even a self-signed cert, in which case you should either add that cert to the default truststore or if you can't or don't want to modify your JVM put that cert in a keystore file you use as the truststore. 使用浏览器或其他工具(例如curlkeytool -printcert -sslserver host[:port]查看服务器使用的证书链,并确定它是否使用公共根CA(例如Verisign-now-Symantec-now-Digicert或GoDaddy),它将已经在Java的默认信任库中,或者在“私有” CA甚至是自签名证书中,在这种情况下,您应该将该证书添加到默认信任库中,或者如果您不能或不想修改自己的证书, JVM将该证书放入用作信任库的密钥库文件中。

PS: the ValidatorException causes the SSLHandshakeException not the reverse. PS: ValidatorException 导致 SSLHandshakeException并非相反。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM