I have a client certificate composed of two files (.crt and .key) which I wish to import to a java KeyStore to then use in a SSLContext to sent HTTP requests with Apache's HTTPClient. However, I can't seem to find a way to do this programmatically, most other questions I've found either point to external tools or aren't fit for my case.
My certificate is encoded with the typical 'BEGIN CERTIFICATE' followed by a Base64 encoded string, and the key with 'BEGIN RSA PRIVATE KEY' and then another Base64 encoded string.
This is what I got so far:
private static SSLContext createSSLContext(File certFile, File keyFile) throws IOException {
try {
PEMParser pemParser = new PEMParser(new FileReader(keyFile));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider());
Object object = pemParser.readObject();
KeyPair kp = converter.getKeyPair((PEMKeyPair) object);
PrivateKey privateKey = kp.getPrivate();
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
FileInputStream stream = new FileInputStream(certFile);
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(stream);
KeyStore store = KeyStore.getInstance("JKS");
store.load(null);
store.setCertificateEntry("certificate", cert);
store.setKeyEntry("private-key", privateKey, "changeit".toCharArray(), new Certificate[] { cert });
SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(store, "changeit".toCharArray())
.build();
return sslContext;
} catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException | KeyManagementException | UnrecoverableKeyException e) {
throw new IOException(e);
}
}
Stacktrace:
java.io.IOException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format at me.failedshack.ssltest.SSLTest.createSSLContext(SSLTest.java:80) at me.failedshack.ssltest.SSLTest.main(SSLTest.java:31)
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:216) at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390) at me.failedshack.ssltest.SSLTest.createSSLContext(SSLTest.java:62) ... 1 more
Caused by: java.security.InvalidKeyException: invalid key format at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:330) at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355) at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.(RSAPrivateCrtKeyImpl.java:91) at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:315) at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:212) ... 3 more
Sadly I keep getting an InvalidKeyException when generating the private key from the file.