java HttpsURLConnection并发送客户端证书

时间:2010-11-11 21:43:21

标签: java x509certificate

我正在尝试将客户端证书发送到服务器。我正在HttpURLConnection上构建一个SSLSocketFactory。

我想我需要通过SSLSocketFactory知道的KeyManager提供密钥。我遇到的麻烦就是将密钥输入KeyManager。

私钥和证书位于PEM文件中(并且它们不能位于密钥库文件中)。我知道如何读取/解码文件,我已经成功验证了客户端证书。但是当我尝试将密钥(作为byte [])放入KeyManager时,它会抱怨:java.security.KeyStoreException: key is not encoded as EncryptedPrivateKeyInfo

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null); // init the keystore

// This Fails: it wants it encoded as EncryptedPrivateKeyInfo
ks.setKeyEntry("MyAlias", clientKeyAsBytes, new Certificate[]{clientCert});

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

使这项工作的诀窍是将PEM文件转换为其他格式。我现在用openssl

在外部做了
openssl pkcs8 -topk8 -nocrypt -in key.pem -inform PEM -out client-key.der -outform DER
openssl x509 -in cert.pem -inform PEM -out client-cert.der -outform DER

然后,我成功地将密钥和证书添加到内存密钥库中:

PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(clientKeyAsBytes);
PrivateKey ff = kf.generatePrivate(keysp);

// This works with DER format of key bytes
ks.setKeyEntry("MyAlias", clientKeyAsBytes, new Certificate[]{clientCert});

答案 1 :(得分:1)

我从RSA加密文件中读取私钥时遇到了同样的异常。我修复了这个问题,而不是在它的二进制格式中创建KeyStore中的条目:

keyStore.setKeyEntry(IdentityManagement.ALIAS, privateKey.getEncoded(), new X509Certificate[]{(X509Certificate)cert});

我只是将其创建为关键对象:

keyStore.setKeyEntry(IdentityManagement.ALIAS, privateKey, password.toCharArray(), new X509Certificate[]{(X509Certificate)cert});