In one of my earlier articles on cryptographic basics, I discussed about the 3 basic services provided by cryptographic techniques i.e. confidentiality, integrity and authentication. Let’s see how we can have confidentiality and authentication implemented in a Spring Boot Application.
SSL/TLS establishes an encrypted link between client and server application such that all the communication between the two applications is private and confidential. Also, by having the client and server certificates issued by a CA establishes the trust between the communicating parties and enables the mutual authentication without having them to share any credentials on the wire.
Overview of the sample applications
In this example, there are two Spring Boot Applications-
SecureAppClient – This is the client spring boot application implemented with an embedded tomcat server
SecureAppServer – This is the server spring boot application with provided tomcat runtime i.e. we’ll run this application on the standalone tomcat server
By running client with embedded tomcat and server on standalone tomcat server we’ll be able to see the mutual authentication configuration for each of these two schemes.
Click here for the code on GitHub
In order to enable SSL and mutual authentication, we need following configuration added to the \conf\server.xml file under tomcat installation.
clientAuth=”true” will enable client authentication by asking client to present a valid signed certificate before establishing the secure channel.
Replace the keystore and truststore file paths with your own directories
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" keystoreFile="C:\Users\Aman\STSProj\AppSecurity\serverkeystore.p12" keystorePass="server" truststoreFile="C:\Users\Aman\STSProj\AppSecurity\servertruststore.p12" truststorePass="server">
Add the following system properties in the VM arguments
-Djavax.net.ssl.keyStore="C:\\Users\\Aman\\STSProj\\AppSecurity\\clientkeystore.p12" -Djavax.net.ssl.keyStorePassword="client" -Djavax.net.ssl.trustStore="C:\\Users\\Aman\\STSProj\\AppSecurity\\clienttruststore.p12" -Djavax.net.ssl.trustStorePassword="client"
In case the certificate presented by the server doesn’t match the hostname, one of the workaround to make this working in the development environment is to default verify the hostname.
HttpsURLConnection.setDefaultHostnameVerifier ((hostname, session) -&gt; true);
Following are the keytool commands to generate the keys and certificates
1) Generate server key and self signed server certificate keytool -genkey -alias serverkey -keystore C:\Users\Aman\STSProj\AppSecurity\serverkeystore.p12 -keyalg RSA -storetype PKCS12 2) Generate client key and self signed client certificate keytool -genkey -alias clientkey -keystore C:\Users\Aman\STSProj\AppSecurity\clientkeystore.p12 -keyalg RSA -storetype PKCS12 3) Export the server certificate keytool -export -alias serverkey -file C:\Users\Aman\STSProj\AppSecurity\servercert.cer -keystore C:\Users\Aman\STSProj\AppSecurity\serverkeystore.p12 4) Export the client certificate keytool -export -alias clientkey -file C:\Users\Aman\STSProj\AppSecurity\clientcert.cer -keystore C:\Users\Aman\STSProj\AppSecurity\clientkeystore.p12 5) Import the server certificate into client truststore keytool -importcert -file C:\Users\Aman\STSProj\AppSecurity\servercert.cer -keystore C:\Users\Aman\STSProj\AppSecurity\clienttruststore.p12 -alias servercert 6) Import the client certificate into server truststore keytool -importcert -file C:\Users\Aman\STSProj\AppSecurity\clientcert.cer -keystore C:\Users\Aman\STSProj\AppSecurity\servertruststore.p12 -alias clientcert
2 thoughts on “Spring Boot Mutual Authentication (2 Way SSL/TLS)”
Just cloned the code from GIT and i get the
java.io.FileNotFoundException: C:\Users\Aman\STSProj\AppSecurity\clientkeystore.p12 (No such file or directory)
when trying to run the client.
It would be a nice thing to have the path to the keystore relative.