Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java HttpClient error for no SSL certificate found, using certificate as String within code?

I'm a bit confused in trying to use HttpClient to call an https site that uses a self-signed certificate. I have the code like below, which is enabling me to make the call but then I am getting the error like javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found I have downloaded the certificate from my web browser and understand I can import it to the keystore but I would rather just put it into the code and use it that way, is there a way to do this?

    HttpClient client = new HttpClient();

    EasySSLProtocolSocketFactory easySSLProtocolSocketFactory = new EasySSLProtocolSocketFactory();
    Protocol https = new Protocol("https", easySSLProtocolSocketFactory,
            443);
    Protocol.registerProtocol("https", https);

    BufferedReader br = null;

    String responseString = "";

    GetMethod method = new GetMethod(path);

    int returnCode = client.executeMethod(method);
like image 264
Rick Avatar asked Jun 23 '11 16:06

Rick


1 Answers

Assuming your certificate is in PEM format. You can embed it in the code and use BouncyCastle's PEMReader to turn it into an X509Certificate instance. Once this is done, create a KeyStore instance in memory and put this X.509 certificate in it. Then, instantiate a new SSLContext using that KeyStore as the trust store and make your HTTP client use it.

This would look like this (not tried, remember to close readers and catch exceptions...):

PEMReader pemReader = new PEMReader(new StringReader("----- BEGIN ......");
X509Certificate cert = (X509Certificate) pemReader.readObject();

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry("some name", cert);

TrustManagerFactory tmf = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);

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

Then, use this SSLContext for your connection. You can do this with Apache HttpClient's SSLSocketFactory if you're using version 4.x (or this if you're using version 3.x). I'd suggest using Apache HttpClient 4.x nowadays.

like image 143
Bruno Avatar answered Sep 19 '22 14:09

Bruno