Author: Shyam Kulkarni
In this blog, we will understand two-way ssl and how to configure it for mule applications (using self-signed certificates).
Two Way SSL: (Mutual SSL Authentication)
Execution steps are as follows:-
Step 1: The client application makes an HTTPS call to access the server application’s resource.
Step 2: As the server application receives the request from the client application, it retrieves the server certificate from the keystore and sends it to the client application.
Step 3: The client application gets the certificate and verifies it with the help of its truststore.
Step 4: After the server application’s certificate is successfully verified by the client application, it retrieves its own certificate from the keystore and sends it to the server application.
Step 5: The server application receives the client certificate and verifies this certificate with the help of its own trust store.
Step 6: Once verified, the client generates a session key and encrypts it with the help of the server’s public key, and sends it to the server application.
Step 7: The server application receives this encrypted session key and decrypts it with the help of its private key.
After this SSL/TLS handshake, whenever the data exchange between client and server application happens, data is encrypted by session key from one side and decrypted using the same key on another side.
So to summarize, in 2 way ssl, both client and server application are verifying the certificate and authenticating each other.
Keystore: The Keystore stores the identity of the server, and it contains the certificate and the private key of the identity of the server.
Truststore: The truststore stores all the certificates which server and client trusts.
Generation of Keys/Certificates:
Here, we will be generating private keys and self-signed certificates.
We will be using a keytool utility which is a part of JDK. [You can find this keytool utility under the path JAVA_HOME/bin]
Keytool is a utility to manage keys and certificates.
Step 1: Creating Server Keystore
Create server’s private key and public key using -genkeypair command. The generated key and self-signed certificate will be stored in the server keystore. Public key is wrapped in a self signed certificate.
Command:
keytool -genkeypair -keyalg RSA -alias my-server-demo -keystore server-keystore.jks -storetype jks -keypass pwd4321 -storepass pwd4321 |
In the above command, there are some options used followed by ‘-’ sign. Let’s have a look at them:
-alias:
– Private Key and certificate are stored together as a keystore entry.
– This entry is identified using a unique string known as ‘alias’.
– In this example, we have specified “my-server-demo” as the alias.
*Note: As there can be multiple certificates in the same keystore, so in order to identify the right certficate, alias is used in the command which is used to search the certificate in the keystore.
-keyalg: Algorithm being used to generate key pair. In this example, RSA algorithm is used.
-storetype: Types of keystore are – JKS, PKCS12,etc…. In this example, JKS type is used.
-keypass: specify key password
-storepass: specify keystore password
After the execution of this command, we need to answer some questions.
*Note: Keystore gets created after the execution of above command, if it doesn’t exists prior to this.
Now, we can see the server-keystore being created at the location where you executed the command in CMD.
Step 2: Creating Client Keystore
Create client’s private key and public key using -genkeypair command. The generated key and self-signed certificate will be stored in the client keystore. Public key is wrapped in a self signed certificate.
Command:
keytool -genkeypair -keyalg RSA -alias my-server-demo -keystore client-keystore.jks -storetype jks -keypass pwd4321 -storepass pwd4321 |
After the execution of this command, we need to answer some questions.
Now, we can see the client-keystore being created at the location where you executed the command in CMD.
Step 3: Exporting the server’s public certificate from the server keystore:
Server’s public certificate is required to be installed at the client’s truststore. By this we mean, extracting the public key from the server keystore.
So, In order to retrieve the certificate from the server keystore, we use -exportcert command. We need to fetch the certificate with the same alias used in the previous command.
keytool -exportcert -keystore server-keystore.jks -alias my-server-demo -file server.cer -storepass pwd4321 |
After the execution of the above command, we can see the server’s public certificate being exported from server keystore.
-file: Name which you would like to specify for retrieving certificate.
Step 4: Exporting the client’s public certificate from the client keystore:
Client’s public certificate is required to be installed at the server’s truststore. By this we mean, extracting the public key from the client keystore.
So, In order to retrieve the certificate from the client keystore, we use -exportcert command. We need to fetch the certificate with the same alias used in the previous command.
keytool -exportcert -keystore client-keystore.jks -alias my-server-demo -file client.cer -storepass pwd4321 |
After the execution of the above command, we can see the client’s public certificate being exported from the client keystore.
-file: Name which you would like to specify for retrieving certificate.
Step 5: Importing Server’s Public Certificate into Client’s trust store:
In order to store the server’s public certificate into the client truststore, we need to use the -importcert command.
keytool -importcert -keystore client-truststore.jks -storepass pwd4321 -file server.cer -alias my-server-demo |
After execution of the above command, we can see the client-truststore being created and the server’s public certificate being imported in it.
Step 6: Importing Client’s Public Certificate into Server’s trust store:
In order to store the server’s public certificate into the client truststore, we need to use the -importcert command.
keytool -importcert -keystore server-truststore.jks -storepass pwd4321 -file client.cer -alias my-server-demo |
After execution of the above command, we can see the client-truststore being created and the server’s public certificate being imported in it.
Configuring Two Way SSL in MuleSoft Application:
Step 1: Start Anypoint Studio and create a new mule project named as “two-way-ssl”.
Step 2: Copy the server-keystore.jks, server-truststore.jks and client-truststore.jks, client-keystore.jks which we have generated and paste into src/main/resources.
Step 3: Create a flow server-flow which will act as a server application in our POC.
Step 4: Configure the server-flow as follows:
- Add a Listener, set the Display Name as /server : 8082, set the Path to /server.
- Now, we will do the connector configuration – Click on the green plus icon and a dialog box will appear.
- Set the Protocol to HTTPS, and set the Port to 8082
- Now, head over to the TLS tab -> Under TLS Configuration, Select Edit Inline -> Enter the TrustStore and KeyStore Configuration(see images for config)
- Add a Transform Message and enter the following dataweave script:
%dw 2.0 output application/json — “Server” |
Following images depicts the same configuration that needs to be implemented:-
Step 5: Configure the client-flow as follows:
- Add a Listener, set Display Name as /client : 8081, set Path as /client.
- Now, we will do the connector configuration – Click on the green plus icon and a dialog box will appear
- Set the Protocol to HTTP, and set the Port to 8081
- Add a Request Component, set its Display Name as Call Server – : 8082/server and set the path to /server
- Now, we will do the configuration – Click on the green plus icon and a dialog box will appear.
- Set the Protocol to HTTPS, set Host to localhost and set Port to 8082.
- Now, head over to the TLS tab -> Under TLS Configuration, Select Edit Inline -> Enter the Truststore Configuration(see image for config)
- Add a Transform Message, and Enter the following Dataweave Script:
%dw 2.0 output application/json — payload |
Step 6: Go to Run -> Run Configuration -> Add the following in the VM arguments
-M-Dcom.ning.http.client.AsyncHttpClientConfig.acceptAnyCertificate=true
And Run the application.
Step 7: Open any Rest Client(e.g Postman) and enter the following in the URL:
http://localhost:8081/client
You will be able to see the Output as “Server”