Step by Step guide to Enable HTTPS or SSL correct way on Apache Tomcat Server – Port 8443

Last updated
App Shah
Crunchify » Apache Tomcat Tutorials » Step by Step guide to Enable HTTPS or SSL correct way on Apache Tomcat Server – Port 8443

It’s been almost 12 years I started using Apache Tomcat. I believe when I did my 1st under grade project, it was on Tomcat version 1.x. Now it’s already on version 8.0. Mostly I’ve been in touch with Tomcat Server in my daily work life, simply can’t live without it.

On Crunchify we have already published almost 40 articles on Apache Tomcat. In most of the tutorial I’ve run server on port 8080 which is default port configured in server.xml file.

In this tutorial we will go over all steps in details on how to enable HTTPS/SSL on Apache Tomcat Server.

Let’s get started:

Step-1. Create Keystore

keytool: we will generate secure key using keytool command – which is key and certificate management tool.

Command:
bash-3.2$ pwd
/Users/Shared

bash-3.2$ keytool -genkey -alias crunchify -keyalg RSA -keystore /Users/Shared/crunchify.keystore

File will be created under folder /Users/Shared.

bash-3.2$ keytool -genkey -alias crunchify -keyalg RSA -keystore /Users/Shared/crunchify.keystore
Enter keystore password:  
Re-enter new password: 
What is your first and last name?
  [Unknown]:  App Shah
What is the name of your organizational unit?
  [Unknown]:  Crunchify, LLC
What is the name of your organization?
  [Unknown]:  Crunchify
What is the name of your City or Locality?
  [Unknown]:  New York City
What is the name of your State or Province?
  [Unknown]:  NY
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=App Shah, OU="Crunchify, LLC", O=Crunchify, L=New York City, ST=NY, C=US correct?
  [no]:  yes

Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 90 days
	for: CN=App Shah, OU="Crunchify, LLC", O=Crunchify, L=New York City, ST=NY, C=US

I’m using Mac OS X, so replace your path accordingly if you are on windows. I’ve used password 123456.

Generate crunchify.keystore for Apache Tomcat HTTPS Setup - Crunchify Tips

Step-2. Create Self Signed Certificate Signing Request

bash-3.2$ keytool -certreq -keyalg RSA -alias crunchify -file crunchify.csr -keystore crunchify.keystore 
Enter keystore password:

Enter password: 123456

Step-3. Let’s check first tomcat is running on port 8080 over HTTP.

Start tomcat server using command: <tomcat_home>/bin/startup.sh.

Make sure you are in correct tomcat path location.

bash-3.2# pwd
/Users/Shared/apache-tomcat-9.0.30/bin

bash-3.2$ ./startup.sh 

Using CATALINA_BASE:   /Users/Shared/apache-tomcat-9.0.30
Using CATALINA_HOME:   /Users/Shared/apache-tomcat-9.0.30
Using CATALINA_TMPDIR: /Users/Shared/apache-tomcat-9.0.30/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home
Using CLASSPATH:       /Users/Shared/apache-tomcat-9.0.30/bin/bootstrap.jar:/Users/Shared/apache-tomcat-9.0.30/bin/tomcat-juli.jar
Tomcat started.

Hit URL: http://localhost:8080 to make sure server is up and running.

Make sure Apache Tomcat is running

Step-4. Now check tomcat instance on port 8443 over HTTPS.

  • Now check port 8443 (HTTPS/SSL URL).
  • Hit URL: https://localhost:8443
  • You should see error message. Page shouldn’t load at all.
Apache Tomcat Server Startup fails without proper cert

Step-5. Update /conf/server.xml file

As we have generated keystore and certificate signing request above, we need to tell tomcat to use that.

  • Open server.xml file which is located at <tomcat_home>/conf/ folder and modify settings.
  • In our case it’s /Users/Shared/apache-tomcat-9.0.30/conf folder.

Add below section directly to server.xml file:

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               keystoreFile="/Users/Shared/crunchify.keystore" keystorePass="123456"
               clientAuth="false" sslProtocol="TLS" sslVerifyClient="optional"
			   sslEnabledProtocols="TLSv1.2,TLSv1.1,SSLv2Hello"/>
  • Here password is 123456 which I used in Step-1.
  • Protocol: HTTP/1.1
Enable HTTPS in server.xml file for Apache Tomcat

Save file. Next we will stop and start Tomcat Server.

Step-6. Stop and Start Apache Tomcat.

  • bash-3.2$ /Users/Shared/apache-tomcat-9.0.30/bin/shutdown.sh
  • bash-3.2$ /Users/Shared/apache-tomcat-9.0.30/bin/startup.sh
bash-3.2$ /Users/Shared/apache-tomcat-9.0.30/bin/shutdown.sh 

Using CATALINA_BASE:   /Users/Shared/apache-tomcat-9.0.30
Using CATALINA_HOME:   /Users/Shared/apache-tomcat-9.0.30
Using CATALINA_TMPDIR: /Users/Shared/apache-tomcat-9.0.30/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home
Using CLASSPATH:       /Users/Shared/apache-tomcat-9.0.30/bin/bootstrap.jar:/Users/Shared/apache-tomcat-9.0.30/bin/tomcat-juli.jar
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED

bash-3.2$ /Users/Shared/apache-tomcat-9.0.30/bin/startup.sh 

Using CATALINA_BASE:   /Users/Shared/apache-tomcat-9.0.30
Using CATALINA_HOME:   /Users/Shared/apache-tomcat-9.0.30
Using CATALINA_TMPDIR: /Users/Shared/apache-tomcat-9.0.30/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk-13.0.1.jdk/Contents/Home
Using CLASSPATH:       /Users/Shared/apache-tomcat-9.0.30/bin/bootstrap.jar:/Users/Shared/apache-tomcat-9.0.30/bin/tomcat-juli.jar
Tomcat started.

Step-7. Check HTTPS url and certification: https://localhost:8443

Now hit HTTPS secure URL again to check you page loaded successfully.

Chrome:

  • By default Chrome Blocks all insecure HTTPS sites from loading.
  • Enable Chrome flag to load invalid certificates for resources loaded from localhost
  1. Go to Chrome
  2. Open Tab
  3. type: chrome://flags/#allow-insecure-localhost
  4. Enable flag from drop down
  5. Relaunch Chrome
Google Chrome allow-insecure-localhost - Apache Tomcat

Safari and Mozilla Firefox:

  • Accept invalid certificate error and visit site.

You should see Apache Tomcat page loading over HTTPS on port 8443 🙂

Apache tomcat running on port 8443 over HTTPS

You are all set. Have you noticed red padlock? Don’t worry. We haven’t purchase SSL cert from Verisign or Comodo.

In production environment you may not see that red cross sign.

Click on certificate in browser and our default self signed certificate should be valid for 90 days.

Check out Crunchify Certificate which we have created in step-1

Bonus point:

How to check your cert content using command keytool?

bash-3.2# keytool -list -keystore /Users/<username>/crunchify.keystore

Result:

bash-3.2$ keytool -list -keystore /Users/Shared/crunchify.keystore

Enter keystore password:  
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

crunchify, Apr 24, 2020, PrivateKeyEntry, 
Certificate fingerprint (SHA-256): 9D:26:77:E0:E8:79:5B:46:57:64:04:95:B8:22:9C:E2:9F:A4:82:CB:01:B5:80:62:75:90:48:27:5F:60:CB:C8

bash-3.2$

Tomcat Port is already in use error?

are you running Tomcat on linux/mac or Windows?

If mac/linux then you could use below commands:

bash-3.2$ ps -ef | grep tomcat
  502 55589 55587   0  6:34PM ttys001    0:00.00 grep tomcat
bash-3.2$ kill -9 55589

If windows then

You could launch Task Explorer and search for Tomcat then right click on that and Kill Process.

Hope that helps. Let me know if that doesn’t work.

21 thoughts on “Step by Step guide to Enable HTTPS or SSL correct way on Apache Tomcat Server – Port 8443”

  1. Thank you so much for this article! After three days of useless tries using this option `#allow-insecure-localhost` for Chrome I was finally able to connect to localhost, wohoo! Using Mac OS, Tomcat 9.0.71.

    Reply
  2. HiiI am getting error as below in below image configuration

    /usr/local/tomcat/conf # cat /etc/os-release
    NAME="Alpine Linux"
    ID=alpine
    VERSION_ID=3.8.1
    PRETTY_NAME="Alpine Linux v3.8"
    HOME_URL="http://alpinelinux.org"
    BUG_REPORT_URL="http://bugs.alpinelinux.org"
    
    
    /usr/local/tomcat/conf # ./../bin/configtest.sh
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr/lib/jvm/java-1.7-openjdk/jre
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Jan 24, 2023 2:49:33 PM org.apache.tomcat.util.digester.Digester fatalError
    SEVERE: Parse Fatal Error at line 91 column 32: Attribute "maxThreads" was already specified for element "Connector".
    org.xml.sax.SAXParseException; systemId: file:/usr/local/tomcat/conf/server.xml; lineNumber: 91; columnNumber: 32; Attribute "maxThreads" was already specified for element "Connector".
            at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
            at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
            at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
            at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
            at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1465)
            at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanAttribute(XMLDocumentFragmentScannerImpl.java:1554)
            at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1314)
            at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2781)
            at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
            at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:504)
            at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:849)
            at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:778)
            at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
            at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
            at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:642)
            at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1449)
            at org.apache.catalina.startup.Catalina.load(Catalina.java:564)
            at org.apache.catalina.startup.Catalina.load(Catalina.java:615)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:606)
            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:308)
            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:487)
    
    Jan 24, 2023 2:49:33 PM org.apache.catalina.startup.Catalina load
    WARNING: Catalina.start using conf/server.xml: Attribute "maxThreads" was already specified for element "Connector".
    Configuration error detected!
    Reply
    • Hi Salman – we have just re-written complete article with all updated steps.

      Kindly take a look and everything should be working fine now. Happy coding.

      Also, don’t hesitate to update if anything is missing in above tutorial.

      Reply
  3. Hello App shah,
    Good day and thanks for this.. Actually the ssl is installed on our end already but the files in the directory is not serving on https..i have tried different approaches through .htacess but couldn’t get it work.. Please take a look here at afrikpulse(dot)com.. Any support will be appreciate.. I want all files e.g style, JavaScript and others to be served under ssl.. Thanks

    Reply
    • Hi Mikahil – thanks for reaching out.

      Could you let me know error message? Also, I’ve just updated above tutorial and you should see all new instructions.

      Reply
  4. Unsupported protocol
    The client and server don’t support a common SSL protocol version or cipher suite.

    Please help me to configure https

    Reply
    • Hi Ravindra – can you send screenshot? Also, make sure you follow tutorial completely. It should work seamlessly.

      Reply
  5. Hi,

    We are testing this on production environment and we bought ssl from GoDaddy. As we already have 8443 utilised by some other application, we can not use it now. So we have tried to configure Tomcat SSL in 443 port. After configuring when i enter https://domain. com:443 it redirects to https://domain. com. So i can not access my tomcat apps.

    Reply
    • You should. As far as you can access your domain without any port you should be good. The reason might be ==> 443 is the default port used by secure http.

      Reply
      • Thanks for your reply. Then how to access my Tomcat apps? If I try to access on the way as folder structure jsp files not working. If I put https://domain.com:8443 it redirects to document root. Can you please suggest how to access Tomcat apps with https in my case?

        Reply
        • Got it. I’m able to reproduce your scenario. I don’t have correct answer but would suggest to try some other port.. How about using port 4444? Between you have a choice using port between 101 to 65000 🙂

          Reply

Leave a Comment