我尝试使用Java连接到ssl服务器。我已经设法在Python中做到了这一点,但是我有一个PEM
文件,Java不支持。将其转换为PKCS12
无法正常工作
尝试连接时出错:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我的问题是:你能给我Java等价物吗? (使用另一个库也可以)
import ssl
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysslsock = ssl.wrap_socket(mysock, keyfile='mykey.pem', certfile='mycert.pem')
mysslsock.connect(("SOMEHOST", XXXXX))
请注意,服务器需要客户端身份验证。
修改
这就是我在Java中所做的:
我使用openssl将证书转换为PKCS12格式:
openssl pkcs12 -export -out mystore.p12 -inkey mykey.pem -in mycert.pem
然后我使用了JDK附带的keytool将其转换为JKS:
keytool -importkeystore -destkeystore mystore.jks -srcstoretype PKCS12 -srckeystore mystore.p12
这就是我的Java代码:
System.setProperty("javax.net.ssl.keyStore", "mystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) socketFactory.createSocket(HOST, PORT);
socket.startHandshake(); // That's the line I get the exception
socket.close();
我确定我犯了一些非常愚蠢的错误,因为我没有任何SSL使用经验。
修改 可能我以某种方式错误的证书,以便他们看起来像这样:
<mykey.pem>
-----BEGIN RSA PRIVATE KEY-----
ljnoabndibnwzb12387uGJBEIUQWBIDAB
....... (Some more lines)
-----END RSA PRIVATE KEY-----
<mycert.pem>
Bag Attributes
localKeyId: XX XX XX XX
subject:...
issuer:...
-----BEGIN CERTIFICATE-----
LAinaw8921hnA.......
.....
-----END CERTIFICATE-----
答案 0 :(得分:1)
您是否需要将密钥加载到Java密钥库中?
这是一个单独的计划。
http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html
-importcert {-alias alias} {-file cert_file} [-keypass keypass] {-noprompt} {-trustcacerts} {-storetype storetype} {-keystore keystore} [-storepass storepass] {-providerName provider_name} {-providerClass provider_class_name {-providerArg provider_arg}} {-v} {-protected} {-Jjavaoption}
读取证书或证书链(提供后者的地方) 来自的PKCS#7格式的回复或一系列X.509证书) file cert_file,并将其存储在别名标识的密钥库条目中。如果 没有给出文件,从stdin中读取证书或证书链。
keytool可以导入X.509 v1,v2和v3证书以及PKCS#7 格式化的证书链,由该类型的证书组成。该 要导入的数据必须以二进制编码格式提供,或者以 可打印的编码格式(也称为Base64编码)由 Internet RFC 1421标准。在后一种情况下,编码必须是有界的 在开头是一个以“----- BEGIN”开头的字符串,并以。为界 最后是一个以“----- END”开头的字符串。