使用 pem 证书打开 SSL 套接字

Opening a SSL socket using a pem certificate

我正在尝试使用 Java 连接到 ssl 服务器。我已经在 Python 中做到了这一点,但是我有一个 Java 不支持的 PEM 文件。将其转换为 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-----

您不需要将密钥加载到 Java 密钥库吗?

那是一个单独的程序。

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/keytool.html

-importcert {-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 证书中)来自 文件 cert_file,并将其存储在由别名标识的密钥库条目中。如果 没有给出文件,从标准输入读取证书或证书链。

keytool 可以导入 X.509 v1、v2 和 v3 证书,以及 PKCS#7 由该类型的证书组成的格式化证书链。这 要导入的数据必须以二进制编码格式或以 可打印编码格式(也称为 Base64 编码)由 互联网 RFC 1421 标准。在后一种情况下,编码必须有界 以“-----BEGIN”开头的字符串开头,并以 以“-----END”开头的字符串结尾。