What I’m planning to do is writing a client-server application that uses a SSL (TLS) connection to exchange data.
As the client is downloadable and I can not guarantee access to the keystore I’m looking for a way to import certificates at runtime.
What I need:
- A way to import the server’s public key/certificate into the client application
- A way to import the server’s private key/certificate into the server application
What I found out so far:
// load the server's public crt (pem), exported from a https website
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(new
FileInputStream("C:\\certificate.crt"));
// load the pkcs12 key generated with openssl out of the server.crt and server.key (private) (if the private key is stored in the pkcs file, this is not a solution as I need to ship it with my application)
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("C:\\certificate.pkcs"), "password".toCharArray());
ks.setCertificateEntry("Alias", cert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
// create SSLContext to establish the secure connection
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
This does not work for me as I’m getting an error:
java.security.KeyStoreException: TrustedCertEntry not supported at ks.setCertificateEntry(“Alias”, cert);
Also, I think pkcs12 is used to store private keys which is not what I want.
I’m new to java and I’m really stuck with that problem now.
Thanks in advance,
Kazuo
Sun’s implementation of
#PKCS12does not allow to store trusted certificates if are not part of the chain of the private key.If you need to use
#PKCS12you have to switch to a different provider e.g. Bouncy Castle supports this.If you do not have a requirement on keystore type you can switch to
JKSwhich is java’s keystore and allows to set trusted certificates (i.e. not part of the private key).For
JKSyou can use the default provider i.e. SUN.UPDATE:
So your code would have to change as follows:
Now you use the keystore
storein your code which has the server’s trusted certificate and not the private key.From the comments in the code I noticed that you have a PKCS12 created using OpenSSL?
If you already have a p12 then you can not use “JKS” for KeyManager.
You will have to use
PKCS12and load it asPKCS12to use it in thekmf.So you will have to use 2 types in your app