Using SSLContext with just a CA certificate and no keystore
Asked Answered
C

1

24

I need to setup a javax.net.ssl.SSLContext for use in a Jersey-Client application. All I want to do is the context to accept a custom root ca certificate. Is is really true that there is no way around of generating a keystore file and importing the CA certificate?

Cobber answered 29/8, 2013 at 14:31 Comment(0)
C
49

Is is really true that there is no way around of generating a keystore file and importing the CA certificate?

There are way to do it without a keystore file, but since you would have to load the CA certificate you want to trust one way or another, you'll have to load a file or resource somehow.

(You could also certainly implement your own TrustManager that makes all the calls to use the Certification Path API, without using the KeyStore API at all, but that would only increase the complexity of your code, not reduce it. You would also need to understand the Java PKI Programmer's Guide to do this correctly.)

If you really don't want a keystore file, you could use the KeyStore API in memory and load the certificate directly.

Something along these lines should work (not tested):

InputStream is = new FileInputStream("cacert.crt");
// You could get a resource as a stream instead.

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate)cf.generateCertificate(is);

TrustManagerFactory tmf = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); // You don't need the KeyStore instance to come from a file.
ks.setCertificateEntry("caCert", caCert);

tmf.init(ks);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

(Remember to close everything and handle the exceptions.)

Whether loading the certificate this way or loading the certificate into a similar KeyStore instance from a keystore file is more convenient is up to you to decide.

Cattle answered 29/8, 2013 at 15:7 Comment(3)
To anyone coming across this answer, be sure to use the import javax.net.ssl.TrustManagerFactory and NOT com.sun.net.ssl.TrustManagerFactory; the later is now deprecated. Cheers.Sihun
@MattClark Generally, you shouldn't import any com.sun.* or sun.* packages directly anyway.Cattle
In my case the certificate is added by the user (through settings) and arrives as a Base64 string: java.io.InputStream is = new java.io.ByteArrayInputStream( java.util.Base64.getDecoder().decode(cert) ); works like a charm. Thanks!Nihi

© 2022 - 2024 — McMap. All rights reserved.