Java web service over https - How to add a self-signed certificate into a client api?

14,033

Solution 1

I would like to write a client api which could use this service over https with a self-signed certificate. I have a self-signed certificate myCertificate.cer and a keystore containing it.

The server key store do contain the server's self-signed certificate and private key and is used by the server to sign messages and to return credentials to the client.

On the client-side, you need to import the server certificate into the client trust store (and generally, you don't want the private key in the client trust store so you extract a stand-alone certificate file i.e. without the private key and then you import that server certificate in the trust store).

It works but I would like to use myCertificate.cer and not a keystore containing it.

It's not a key store but a trust store and adding the certificate to the client trust store is required because self-signed certificates are not signed by a root CA and are not trusted by default. So you need to create a chain of trust.

Now, you can maybe distribute the trust store in the JAR of the client API. This approach is discussed in this thread (the biggest problem being that you'll have to redistribute the JAR when the server certificate expires). Personally, I don't really like this solution.

IMHO, the good solution if you want to skip the trust store stuff would be to buy a real certificate from a widely-known certificate vendor for which you already have root CA certificates in the trust store (like Verisign, Thawte).

Solution 2

I would just add the certificate to the cacerts file of the JDK running your app. If you do this then you won't have to do anything else. The code you have above wouldn't be required. You add the certificate to the keystore by running a command similar to below:

C:/<jdk-version/bin/keytool -import -alias myalias -file mycert.crt -keystore C:/<jdk-version>/jre/lib/security/cacerts
Share:
14,033
Admin
Author by

Admin

Updated on June 23, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a "Hello World" web service created with axis2. I would like to write a client api which could use this service over https with a self-signed certificate. I have a self-signed certificate myCertificate.cer and a keystore containing it.

    Here is my client API :

    public class MyApi{
    
    public Object callMyService(){
    
    Axis2TestStub stub = new Axis2TestStub(
    "https://localhost:8443/axis2/services/Axis2Test");
    
    System.setProperty("javax.net.ssl.trustStore",
    "src/main/resources/myKeystore.jks")
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
    
    Hello request = new Hello();
    request.setMot("World");
    HelloResponse response = stub.hello(request);
    Object mot = response.get_return();
    return mot;
    

    It works but I would like to use myCertificate.cer and not a keystore containing it. Does someone know how to do that? I tried to override https protocol with no success :

    HttpSecureProtocol myHttpsProtocol = new HttpSecureProtocol();
    myHttpsProtocol .setCheckHostname(false);
    myHttpsProtocol .addTrustMaterial(new TrustMaterial("myCertificate.cer"));
    Protocol customHttps = new Protocol("https", 
    (ProtocolSocketFactory) myHttpsProtocol , 8443);
    Protocol.registerProtocol("https", customHttps);
    
  • Taylor Leese
    Taylor Leese about 14 years
    +1 for suggesting the use of a certificate from a well known issuer.