Reputation: 1652
I'm trying to send a Client certificate to the server. I'm constructing a SSLSocketFactory on a HttpURLConnection.
I think I need to make the key available via a KeyManager that the SSLSocketFactory knows about. The trouble I'm having is getting the key into the KeyManager.
The private key and certificate are in a PEM file (and they can't be in a keystore file). I know how to read/decode the file and I've successfully validated the client certificate. But when I try to put the key (as byte[]) into the KeyManager, it complains: 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});
What's the right way to do this?
Upvotes: 1
Views: 4108
Reputation: 615
I got the same exception for reading the private key from an RSA encrypted file. I fixed the issue by instead of creating the entry in the KeyStore in it's binary format:
keyStore.setKeyEntry(IdentityManagement.ALIAS, privateKey.getEncoded(), new X509Certificate[]{(X509Certificate)cert});
I simply create it as a Key Object instead:
keyStore.setKeyEntry(IdentityManagement.ALIAS, privateKey, password.toCharArray(), new X509Certificate[]{(X509Certificate)cert});
Upvotes: 1
Reputation: 1652
The trick to making this work was to convert the PEM file to a different format. I did it externally for now with 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
Then, I was successfully able to add the key and certificate to the in-memory keystore:
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});
Upvotes: 2