I'm given a self-signed client certificate kit that is to be used to access a server via HTTPS. The kit consists of the following PEM files:
- client.crt (client certificate)
- client.key (client private key)
- ca.crt (CA certificate)
One way to solve the task is to generate a Java keystore:
- Use openssl to convert client certificate and key to PKCS12 keystore
- Use keytool to import CA certificate to the store
... and then use code like the following to build SSLSocketFactory instance:
InputStream stream = new ByteArrayInputStream(pksData);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(stream, password);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmfactory.init(keyStore);
TrustManager[] trustManagers = tmfactory.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
sslSocketFactory = sslContext.getSocketFactory();
... which is later used to init http library.
So we obtain a KeyStore, then init KeyManagers and TrustManagers with its help and finally we build SSLSocketFactory instance with them.
The question is: is there a way to avoid that keystore file creation and somehow build SSLSocketFactory starting with PublicKey and Certificate instance (which, for example, can be obtained from PEM files using bouncycastle's PemReader)?
It turned out that a KeyStore instance still has to be built, but it can be done in memory (starting with PEM files as input), without using an intermediate keystore file build with keytool.
To build that in-memory KeyStore, code like the following may be used:
The idea is taken from Programmatically Obtain KeyStore from PEM