TLS is a cryptographic protocol that provides secure communication. The 2-way TLS ensures that both parties involved in the communication are identifying each other before a connection is made (regardless if the communication is user-to-user, user-to-machine or machine-to-machine).
In order to demonstrate the two-way TLS authentication between the applications, we are going to make the following:
- Generate a client and server keystores and truststores (using Java Keytool)
- Create simple Mule app
- Configure TLS globally in Mule
Generate client/server keystores and truststores
Client/server keystores and trustores have different contents:
- server’s keystore contains the private and the public key of the server and the truststore contains certificates of the trusted clients
- client’s keystore contains the private and the public key of the client, while the truststore contains certificates of the trusted servers
The keystore contains one or two passwords:
- password for or accessing the keystore file
- keyPassword for accessing the server’s private key in the keystore

1. Generate server keystore
keytool -genkey -alias localhost -keyalg RSA -keystore server-keystore.jks -dname "CN=localhost,OU=dev,O=InterWorks,L=Bitola,ST=Macedonia,C=MK" -validity 364876 -keysize 2048 | |
Enter keystore pass: serverkeystorepass | |
Enter key password for <localhost>: serverkskeypass |
2. Generate client keystore
keytool -genkey -alias localhost -keyalg RSA -keystore client-keystore.jks -dname "CN=localhost,OU=dev,O=InterWorks,L=Bitola,ST=Macedonia,C=MK" -validity 364876 -keysize 2048 | |
Enter keystore pass: clientkeystorepass | |
Enter key password for <localhost>: clientkskeypass |
3.Export the client certificate [client.crt] from the client-keystore.jks
keytool -export -alias localhost -keystore client-keystore.jks -file client.crt | |
Enter keystore pass: clientkeystorepass |
4. Create server truststore and import the client.crt
keytool -import -alias localhost -keystore server-truststore.jks -file client.crt | |
Enter keystore pass: servertskeystorepass | |
Trust this certificate? [no]:yes |
5. Export the server certificate [server.crt] from the server-keystore.jks
keytool -export -alias localhost -keystore server-keystore.jks -file server.crt | |
Enter keystore pass: serverkeystorepass |
6. Create client truststore and import the server.crt
keytool -import -alias localhost -keystore client-truststore.jks -file server.crt | |
Enter keystore pass: clienttskeystorepass | |
Trust this certificate? [no]:yes |
Useful commands:
Create a simple Mule project and configure 2-way TLS



We are going to use 3 simple Mule applications (3 layers). No complex logic there. The first application has an HTTP receiver that runs on port 8092 that is going to receive the GET call. This application will call the pl application. In the end, the pl is going to call the sl application where we are setting some payload:
The next step is to set the configuration for mutual authentication:
1. Copy the generated keystores/truststores in the projects (under src/main/resources)
2.Define TLS Context globally and configure the 2-way TLS
- el-iw-two-way-tls

Configure the HTTP Request
<tls:context name="Consumer_TLS_Context" enabledProtocols="TLSv1.1, TLSv1.2" doc:name="TLS Context"> | |
<tls:trust-store path="${client_trustStore.path}" password="${client_trustStore.password}" type="jks"/> | |
<tls:key-store type="jks" path="${client_keyStore.path}" alias="${client_keyStore.alias}" keyPassword="${client_keyStore.keyPassword}" password="${client_keyStore.password}"/> | |
</tls:context> | |
<http:request-config name="PL_HTTP_Request_Configuration" protocol="HTTPS" host="${pl-iw-two-way-tls.host}" port="${pl-iw-two-way-tls.port}" basePath="${pl-iw-two-way-tls.basePath}" doc:name="HTTP Request Configuration" connectionIdleTimeout="${connection.idle.timeout}" responseTimeout="${connection.response.timeout}" tlsContext-ref="Consumer_TLS_Context"/> |
- pl-iw-two-way-tls


Configure the HTTP listener
Configure the HTTP Request
<tls:context name="host_TLS_Context" doc:name="TLS Context"> | |
<tls:trust-store path="${host_TrustStore.path}" password="${host_TrustStore.password}" type="jks"/> | |
<tls:key-store type="jks" path="${host_KeyStore.path}" alias="${host_KeyStore.alias}" keyPassword="${host_KeyStore.keyPassword}" password="${host_KeyStore.password}"/> | |
</tls:context> | |
<http:listener-config name="PL_HTTP_Localhost_Listener_Configuration" host="0.0.0.0" port="8077" doc:name="HTTP Listener Configuration" connectionIdleTimeout="${connection.idle.timeout}" tlsContext-ref="host_TLS_Context" protocol="HTTPS" basePath="/api"/> | |
<tls:context name="consumer_TLS_Context" enabledProtocols="TLSv1.1, TLSv1.2" doc:name="TLS Context"> | |
<tls:trust-store path="${client_TrustStore.path}" password="${client_TrustStore.password}" type="jks"/> | |
<tls:key-store type="jks" path="${client_KeyStore.path}" alias="${client_KeyStore.alias}" keyPassword="${client_KeyStore.keyPassword}" password="${client_KeyStore.password}"/> | |
</tls:context> | |
<http:request-config name="SL_HTTP_Request_Configuration" protocol="HTTPS" host="${sl-iw-two-way-tls.host}" port="${sl-iw-two-way-tls.port}" basePath="${sl-iw-two-way-tls.basePath}" tlsContext-ref="consumer_TLS_Context" doc:name="HTTP Request Configuration" connectionIdleTimeout="${connection.idle.timeout}" responseTimeout="${connection.response.timeout}"/> |
- sl-iw-two-way-tls

Configure the HTTP Listener
Note: The details of TLS connection negotiations can be seen in the console if we add the below command when we run our applications in debug mode:
-Djavas.net.debug=all or -Djavax.net.debug=ssl:handshake