Recents
Consuming web services under https in JavaUnofficial Content

Version en Español

Importing certificates and managing the keystore in Java.#

This process comprises two stages:

1) Saving the server certificate in a keystore; and

2) Consuming the web service and indicating the location of the keystore with the certificate to the application.

In some cases, we also need to:

3) Setting up a client certificate (pfx) in the Java keystore

 

1) Saving the server certificate in a keystore#

First, it must be made clear that, for communicating with an https resource, we must have installed the server certificate with which we seek communication. Such certificate contains the public key used to encrypt the information sent, only to be decoded by the server with its private key (read more here). So, at the time of consuming a service under https, we will need the server certificate in order to establish our communication. 

After obtaining the certificate we must save it in a keystore. A keystore is "a store with certificates" allowing us to add new certificates or delete others, among other possibilities. A way to handle/manage keystores is by using the "Keytool.exe" tool in the JDK.

The above may be summarized into two simple steps:

1.1) Obtaining the certificate#

With the IExplorer go to the server from which you want to obtain the certificate (https://www.dominio.com/webservice). Then go to  File->Properties->Certificates. In 'Details' go to 'Copy to File...' and select, for instance, 'Base-64 encoded X.509'. By doing this you will be saving the certificate in a file.

Web service seguro/autenticación - wsdl certificado

1.2) Adding the certificate to a keystore

Add the certificate (ex) "certif.cer" in the keystore MiKeystore:

C:\>"c:\Program Files\Java\jdk1.5.0_05\bin\keytool.exe" -import -file certif.cer -keystore c:\MiKeystore -storepass MiPassword

2) Setting up the keystore created in the Java app (in the Java TrustStore)#

2.1) In Java command line applications#

After the steps described above, you must indicate the location of the keystore to the application so that, when the time comes to establish communication, it will know where to take the certificate from. To do this you must set up the system properties: javax.net.ssl.trustStore, and  javax.net.ssl.trustStorePassword. It is usual to add the properties to the instance of the virtual machine. This may be done in the GX Interpreter Options in the case of a win application, or by adding these entries to the Java options of the Tomcat for the case of a web application.

You may otherwise set up by code, adding the following lines to the routine that consumes the service (or to any other part of the application executed prior to consuming the service):

java System.setProperty("javax.net.ssl.trustStore", "C:\\MiKeystore");
java System.setProperty("javax.net.ssl.trustStorePassword", "MiPassword");

2.2) In Java Web applications with Tomcat#

The same steps apply in this case for saving the certificate, except that here, the trustore is not configured with our own keystore (Mykeystore). We must include it in the keystore of the tomcat located at %JAVA_HOME%\lib\security\cacerts

The following command is used for the inclusion:

keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>

For example:

C:\Program Files\Java\jre1.8.0_51\bin>keytool -import -noprompt -trustcacerts -alias fortigate -file   C:\mykeystore\fortigateinf.cer -keystore ..\lib\security\cacerts

To list and verify that we have added the certificate, use the following sentence:

keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

NOTE: the default password for the keystore is changeit

Then we have to set up the trustore with that keystore, and to do it we have two options:

a. At the application level, by embedding the following in the GeneXus code:

java System.setProperty("javax.net.ssl.trustStore", "C:\\...\\jre\\lib\\security\\cacerts");
java System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

b. Or the option of adding the following properties to the Tomcat:

-Djavax.net.ssl.trustStore= %JAVA_HOME%\lib\security\cacerts
-Djavax.net.ssl.trustStorePassword=changeit

i2015_08_12_18_18_301_png

Afterwards we must restart the webserver (Tomcat) 

IMPORTANT: In some cases we might get the following error when invoking the webservice:

javax.net.ssl.SSLException:
Connection has been shutdown:
avax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to findvalid certification path to requested target

Solution: This error occurs because after going over the whole hierarchy of .cer files, no reliable Certifying Authority was found. This means that the certificate was subscribed with an unreliable signature (meaning that it is not in the keystore). In such cases, view all certificates in the site and add them all to the keystore using a different alias for each case (option -alias of the option -import)

For example, if the certif.cer includes any reference to another certificate (Double Click with the .cer and then Certification Path, to get a tree with several certificates). You must download each of such certificates (.cer)  and execute a keytool. command similar to the previous one, by changing the alias for each file. It would be something like this:  

keytool -import -noprompt -trustcacerts -alias certif2 -file certif2.cer -keystore "C:\Program Files (x86)\Java\jre1.8.0_91\lib\security\cacerts" -storepass changeit

3) Setting up a client certificate (pfx) (in the Java keystore) when necessary#

There are cases where we need to send a certificate from the client, including a private key (.pfx). In such cases we must do the following:

3.1) Import the client certificate in a new keystore by doing the following:#

keytool.exe -importkeystore -destkeystore <nombreKeyStore> -srckeystore <ruta archivo pfx>\archivo.pfx -srcstoretype pkcs12 -deststoretype JKS -srcstorepass <password>

The keystore cannot be the same one than that of the trustStore.#

We also need that the password  of the certificate be the same as the passworld of the new keystore.#

When the certificate password complies with the minimum security rules (like having more than six digits), we may create the new keystore with the same password that corresponds to the certificate. Otherwise, we will have to change the password of the client certificate so that it matches that of the KeyStore.

In order to change the certificate password: 

  • Get the alias of the certificate:
keytool.exe -list -v -keystore <nombreKeyStore>
  • Change the password doing the following:
keytool.exe -keypasswd -alias <alias> -keystore <nombreKeyStore>

3.2)  Setting up the Java Keystore with the keystore created#

To this end, we have two options:

a. At the application level, by embedding the following in the GeneXus code

java System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
java System.setProperty("javax.net.ssl.keyStore", "C:\\ClientCertificate\\cacerts2");
java System.setProperty("javax.net.ssl.keyStorePassword", "Password");

b. To add the following properties in the Tomcat:

-Dsun.security.ssl.allowUnsafeRenegotiation=true
-Djavax.net.ssl.keyStore=C:\ClientCertificate\cacerts2
-Djavax.net.ssl.keyStorePassword=changeit2
-Djavax.net.ssl.keyStoreType=JKS