Search code examples
ssltomcatcertificatessl-certificatekeytool

How to create local SSL certificate with local CA for a local server


I'm trying to generate my own SSL certificate using keytool for my java servlet application running on Tomcat 9. I'm generating certificate with this script:

rem 1) Key-Pair Generation For Client with:
keytool -genkey -keyalg RSA -keysize 1024 -keystore C:\cert\client1ks.jks -storepass test1234 -alias client1 -keypass client1pass -dname "CN=testuser1, OU=tmdev, O=dev, L=ist, ST=tr, C=tr"

rem 2) Public Cer Exported for Client with: test1public.cer
keytool -keystore C:\cert\client1ks.jks -storepass test1234 -alias client1 -keypass client1pass -exportcert  -file C:\cert\test1public.cer

rem 3) Add extracted Client Public Cer to trusted store of Server KeyStore:
keytool -keystore "C:\cert\server.jks" -storepass server1234 -import -file "C:\cert\test1public.cer" -alias trustedclient1

rem 4) Key-Pair Generation For Server with:
keytool -genkey -keyalg RSA -keysize 1024 -keystore C:\cert\server.jks -storepass server1234 -alias server1 -keypass server1pass -dname "CN=server1, OU=tmdev, O=dev, L=ist, ST=tr, C=tr"

rem 5) Server Cer Exported for Client with: test1public.cer
keytool -keystore C:\cert\server.jks -storepass server1234 -alias server1 -keypass server1pass -exportcert  -file C:\cert\serverpublic.cer

rem 6) Add extracted Server Public Cer to trusted store of Client KeyStore:
keytool -keystore C:\cert\client1ks.jks -storepass test1234 -import -file C:\cert\serverpublic.cer -alias trustedserver

And I added this in server.xml in Tomcat configuration:

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="443" SSLEnabled="true"
           maxThreads="200" scheme="https" secure="true"
           keystoreFile="C:\cert\client1ks.jks" keystorePass="test1234"
           clientAuth="false" sslProtocol="TLS" />  

But my browser is still showing Your connection to this site is not secure with red lock. Why?


Solution

  • What you did are the steps to setup your server using a self-signed certificate. You did not tell the client (browser) about your server certificate yet.

    Clients like the browsers, have a set of Certificate Authorities (CA's) and Sub CA's it trusts by default. Any certificate signed by these CA/SubCA's will be trusted by the client by default, you don't have to do any additional step for this to happen. But when you are working with a self-signed certificate or a certificate that is signed by a CA that is not trusted by the client, you have to explicitly tell the client to trust the CA or self-signed certificate.

    So to answer your question, since you are working with a self-signed certificate, you have to add this certificate to the browser's truststore. You can find the browsers truststore in the browser settings (usually under security).

    Advanced setup:

    You can create a certificate chain yourself to replicate the chain-of-trust by creating a self-signed CA certificate first, and then you would create a server key pair and create a CSR for that key pair, and have the CA sign the CSR to issue a certificate. You would then associate this certificate to your server key pair. In this case you have to add just the self-signed CA certificate to the browser's truststore. You wouldn't add the server certificate. This is the ideal way of doing it. You could easily do all these steps using the keystore-explorer application, it has nice and easy GUI. If you use this approach, tomorrow if you have a second server you need to secure, all you have to do is generate a key pair for the second server, and follow the same steps as above (except adding the CA certificate to the truststore). You will now be able to launch your second application without any issue on the browser (you won't see the red lock).

    Security Note:

    You would do this only during your development phase. For the production version of your application, you would setup your server with a real certificate signed by a well-known CA.