GoogleSearchBox

Custom Search

Tuesday, June 18, 2013

On Windows, Configuring SSL (https) on tomcat 6 using Win32 Openssl

On Windows, Configuring / Creating  SSL (https) and certificates on tomcat 6 using Openssl.
We will basically generate Key, JavaKeyStore (jks), CSR and Certificate files using Win32 OpenSSL (a Openssl tool for Windows 32 systems).


1. Create a root CA (Certification Authority), self sign it:

1.(a). Lets create a public-private key pair (a file named as: tomcat6CAS-rootCAkey.key), which will be used to self sign our root CA (will be named as: ):
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs> openssl genrsa -out tomcat6CAS-rootCAkey.key 1024

For development environment (like for localhost), we can give a relative name :
> openssl genrsa -out localhostRootCAkey.key 1024


1.(b).  Lets create our Root CA's certificate and self sign this certificate (if you know your server's dns name/ hostname or skip to next):
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs> openssl req -config openssl.cfg -new -x509 -days 3650 -key tomcat6CAS-rootCAkey.key -out tomcat6CAS-rootCAcert.crt


or if it is for localhost :

> openssl req -config openssl.cfg -new -x509 -days 3650 -key  localhostRootCAkey.key -out localhostRootCAcert.crt

2. Create Server certificate:
2.(a). Lets create a key file (containing key-pair) to be used for creating server certificate:
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl genrsa -out localhostServerKey.key 2048 -config openssl.cfg     
   
(if you are using the localhost server for development env)

2. (b). Use above server key to generate a server certificate signing request (CSR) I named it "localhostServerCSR.csr":
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl req -new -key localhostServerKey.key -out localhostServerCSR.csr -config openssl.cfg

Result:
Loading 'screen' into random state - done
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:NewJersey
Locality Name (eg, city) []:Edison
Organization Name (eg, company) [Internet Widgits Pty Ltd]:RSI
Organizational Unit Name (eg, section) []:DDMS
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:abc@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:changeit
An optional company name []:RSI

2.(c). Now lets create a server certificate (localhostServerCert.crt) and sign it using
this server CSR file (localhostServerCSR.csr)
along with rootCA key file (tomcat6CAS-rootCAkey.key) to be certified from the root CA (tomcat6CAS-rootCAcert.crt) :

C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl ca -config openssl.cfg  -keyfile tomcat6CAS-rootCAkey.key -cert tomcat6CAS-rootCAcert.crt  -out localhostServerCert.crt  -infiles localhostServerCSR.csr

Result:
Using configuration from openssl.cfg
Loading 'screen' into random state - done
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jun 18 13:53:26 2013 GMT
            Not After : Jun 18 13:53:26 2014 GMT
        Subject:
            countryName               = US
            stateOrProvinceName       = NewJersey
            organizationName          = RSI
            organizationalUnitName    = DDMS
            commonName                = localhost
            emailAddress              = abc@gmail.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                59:35:A4:C6:8D:91:61:3D:5C:A2:3E:AF:85:D8:D6:59:82:16:7A:38
            X509v3 Authority Key Identifier:
                keyid:9C:E6:C5:57:9A:6A:B9:C2:A0:14:34:86:89:C9:7C:AD:D1:41:7E:19

Certificate is to be certified until Jun 18 13:53:26 2014 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated



Correct command for above is (Changing the policy):
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl ca -config openssl.cfg  -keyfile tomcat6CAS-rootCAkey.key -cert tomcat6CAS-rootCAcert.crt  -out localhostServerCert.crt -policy policy_anything  -infiles localhostServerCSR.csr

3.(a). Create a key (key-pair) file for the Client:
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl genrsa -out client.key 2048

3.(b). Now lets Create a certificate signing request (CSR) for the Client this time:

C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl req -new -key client.key -out client.csr -config openssl.cfg

Result:
Loading 'screen' into random state - done
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:Karnatak
Locality Name (eg, city) []:Bangalore
Organization Name (eg, company) [Internet Widgits Pty Ltd]:RSI
Organizational Unit Name (eg, section) []:Dev
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:abc@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:changeit
An optional company name []:RSI

3.(c). Now lets get this csr signed from the CA and will generate in turn the client certificate for us:

C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl ca -config openssl.cfg -keyfile tomcat6CAS-rootCAkey.key  -cert tomcat6CAS-rootCAcert.crt -out client.crt -policy policy_anything  -infiles client.csr

Result:
Using configuration from openssl.cfg
Loading 'screen' into random state - done
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Jun 18 14:08:56 2013 GMT
            Not After : Jun 18 14:08:56 2014 GMT
        Subject:
            countryName               = IN
            stateOrProvinceName       = Karnatak
            localityName              = Bangalore
            organizationName          = RSI
            organizationalUnitName    = Dev
            commonName                = localhost
            emailAddress              = abc@gmail.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                6B:F5:49:53:3E:C0:02:E4:3A:C3:45:49:85:BE:6E:29:E0:56:F8:A6
            X509v3 Authority Key Identifier:
                keyid:9C:E6:C5:57:9A:6A:B9:C2:A0:14:34:86:89:C9:7C:AD:D1:41:7E:19

Certificate is to be certified until Jun 18 14:08:56 2014 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated


4. Now Lets Use PKCS#12, to bundle certificates with its private key:
PKCS#12 files will be used to import certificates into Java keystores and also to import into client browsers.

4.(a). Bundling server cert file (localhostServerCert.crt) and Exporting as pkcs12 file (localhostServerCertAsPK12.p12) format for Server:

C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl pkcs12 -export -in localhostServerCert.crt  -inkey localhostServerKey.key  -out localhostServerCertAsPK12.p12  -name localhostServCert

Result:
Loading 'screen' into random state - done
Enter Export Password: [abcd]
Verifying - Enter Export Password: [abcd]

4.(b). Bundling client cert file (client.crt) and Exporting as pkcs12 file (client.p12) format for Client:

C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name clientCertificate

Result:
Loading 'screen' into random state - done
Enter Export Password: [abcd]
Verifying - Enter Export Password: [abcd]

Where "localhostServCert" and "clientCertificate"  are alias names for server and client pk12 files respectively.

5. Configuring the Tomcat to enable the SSL and to use a JKS (JavaKeyStore) file:

Use the "keytool" command to generate the JKS file for you. keytool is found inside $JAVA_HOME/bin  where Java version should be 1.6 or greater and assuming that you have the PATH variable configured to include $JAVA_HOME/bin

5.(a). Lets generate a JKS (localhostServerKeystore.jks) file and use it to import the pk12 server file:

C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore localhostServerKeystore.jks -srckeystore localhostServerCertAsPK12.p12  -srcstoretype PKCS12 -alias localhostServCert
Enter source keystore password: [abcd]

5.(b). Copy the server JKS (localhostServerKeystore.jks) file into  %CATALINA_HOME%/conf :

Where CATALINA_HOME is the Tomcat (The Server which you want to enable SSL) root directory.

5.(c). Configuring the Server (Tomcat in our case) to use the server JKS file created above:
Now edit the "server.xml" file located at %CATALINA_HOME%/conf  (or any as per your Tomcat server's configuration):

Look for the section starting with :  <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
This might be commented out. Please Uncomment this block and edit it to include the JKS file location something as below (change the path of JKS file as per your file location in the system):

   <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               keystoreFile="conf/localhostServerKeystore.jks"
               keystorePass="abcd" clientAuth="false" sslProtocol="TLS" />

Also you can use a configuration like below :

    <Connector port="443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
      keystoreFile="conf/localhostServerKeystore.jks"
      keystorePass="abcd" />

Where port="443"  means, the browser will not require/show the port on the address bar.

Now Restart the Tomcat, check for any errors, and there should be none, if some please follow my other posts for related errors.
Type  https://localhost:8443   or  https://< your server's/computer's IP address running tomcat >:8443  or https://localhost:443  (if using port=443)

Now you should get a page like below showing an warning that, This connection is Untrusted:














Now if you click, I understand the Risks (in Firefox browser), and click Add Exception.
And in next window make sure to uncheck the field "Permanently store this exception"  as shown below and then click Confirm Security Exception:

















Now you should see the Apache tomcat's default page running with HTTPs (SSL) successfully.

5.(d). Configuring / Making Browsers trust the server's root CA certificate as not to get above exception page each time:
Please follow this post: http://java-with-shiva.blogspot.in/2013/06/making-our-browsers-trust-servers-root.html

6. Configure the server to require client authentication:

6.(a).  Create a client JKS file (named as cacerts.jks) using the root CA file (tomcat6CAS-rootCAcert.crt):
C:\certs\windowsOpenSSLCerts\tomcat6-CAS-certs>keytool -import -keystore cacerts.jks -storepass changeit -alias casclient_ca  -file  tomcat6CAS-rootCAcert.crt

Result:
Displays the contents of the keystore..

Trust this certificate? [no]:  yes
Certificate was added to keystore

6.(b).  Copy the client jks (cacerts.jks) file created  into  %CATALINA_HOME%/conf:


6.(c).  Configure the Tomcat server's config file (server.xml) to have the cacerts.jks file as below:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150"  scheme="https"  secure="true"
               truststoreFile="/usr/local/apache-tomcat-6.0.37/conf/cacerts.jks"  truststorePass="changeit"
               keystoreFile="/usr/local/apache-tomcat-6.0.37/conf/myServerKeystore.jks"  
               keystorePass="changeit"  clientAuth="false"  sslProtocol="TLS" />