Category Archives: Keytool

Java Keytool and SSL

Keytool is a Java utility to manage a keystore (database) of private keys, certificate chains and trusted certificates. It is included in the Java distribution. Java Keytool stores the keys and certificates in what is called a keystore. A keystore is a password protected file that contains the private key and any certificates necessary to complete a chain of trust and establish the trustworthiness of the primary certificate (purchased SSL certificate). A single keystore can contain multiple private keys and their corresponding certificate chains.

Each certificate in a Java keystore is associated with a unique alias. When creating a Java keystore you will first create the .jks file that will initially only contain the private key. You will then generate a CSR and have a certificate generated from it. Then you will import the certificate to the keystore including any root and intermediate certificates. Java Keytool also contains several other functions that allow you to view the details of a certificate or list the certificates contained in a keystore or export a certificate.

Keytool primer

//List keystore contents
static-202:~ Sayeed$ keytool -list -keystore abc-keystore

//Import SSL certificate into keystore. Import should be in the order: root -> intermed -> primary
static-202:~ Sayeed$ keytool -import -alias root -keystore abc-keystore -trustcacerts -file gdroot-g2.crt
static-202:~ Sayeed$ keytool -import -alias intermed -keystore abc-keystore -trustcacerts -file gdig2.crt 
static-202:~ Sayeed$ keytool -import -alias abc -keystore abc-keystore -trustcacerts -file 4af931ac9e4c59.crt 

Note: The last import i.e. your SSL certificate import should have the same alias as the private key. Only then will it be mapped with the private key which is REQUIRED.

//Delete certificate from keystore
static-202:~ Sayeed$ keytool -delete -alias "root" -keystore abc-keystore

//Convert keystore from jks to pkcs12
static-202:~ Sayeed$ keytool -importkeystore -srckeystore abc-keystore -destkeystore abc-keystore.pcks -srcstoretype jks -deststoretype pkcs12

Note: The above command doesn’t work because pkcs12 keystores are only meant for certificate-private key pairs. Root and intermediates certificates in the jks keystore cannot be exported because their private keys are absent.

//Print certificate details
static-202:~ Sayeed$ keytool -printcert -file mydomain.crt

//Export certificate from keystore
static-202:~ Sayeed$ keytool -export -alias www.mycompany.com -file mydomain.crt -keystore abc-keystore

//View certificate chain
static-202:~ Sayeed$ openssl s_client -connect mycompany.com:443 -showcerts

Keytool commands for Creating and Importing

//Generate a Java keystore and key pair
static-202:~ Sayeed$ keytool -genkey -alias mydomain -keyalg RSA -keystore keystore.jks -keysize 2048

//Generate a certificate signing request (CSR) for an existing Java keystore
static-202:~ Sayeed$ keytool -certreq -alias mydomain -keystore keystore.jks -file mydomain.csr

//Import a root or intermediate CA certificate to an existing Java keystore
static-202:~ Sayeed$ keytool -import -trustcacerts -alias root -file Thawte.crt -keystore keystore.jks

//Import a signed primary certificate to an existing Java keystore
static-202:~ Sayeed$ keytool -import -trustcacerts -alias mydomain -file mydomain.crt -keystore keystore.jks

//Generate a keystore and self-signed certificate (see How to Create a Self Signed Certificate using Java Keytool for more info)
static-202:~ Sayeed$ keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

Keytool commands for Checking

//Check a stand-alone certificate
static-202:~ Sayeed$ keytool -printcert -v -file mydomain.crt

//Check which certificates are in a Java keystore
static-202:~ Sayeed$ keytool -list -v -keystore keystore.jks

//Check a particular keystore entry using an alias
static-202:~ Sayeed$ keytool -list -v -keystore keystore.jks -alias mydomain

Other Keytool commands

//Delete a certificate from a Java Keytool keystore
static-202:~ Sayeed$ keytool -delete -alias mydomain -keystore keystore.jks

//Change a Java keystore password
static-202:~ Sayeed$ keytool -storepasswd -new new_storepass -keystore keystore.jks

//Export a certificate from a keystore
static-202:~ Sayeed$ keytool -export -alias mydomain -file mydomain.crt -keystore keystore.jks

//List Trusted CA Certs
static-202:~ Sayeed$ keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts

//Import New CA into Trusted Certs
static-202:~ Sayeed$ keytool -import -trustcacerts -file /path/to/ca/ca.pem -alias CA_ALIAS -keystore $JAVA_HOME/jre/lib/security/cacerts

Some Helpful OpenSSL commands (openssl installation required)

//Check csr
static-202:~ Sayeed$ openssl req -text -noout -verify -in abc.csr 

//Check certificate
static-202:~ Sayeed$ openssl x509 -in 4af931ac9e4c59.crt -text -noout 

For more information, check out the Java Keytool documentation.

Installing an SSL certificate on Linux / Tomcat7 Server

You would be using Keytool to accomplish most of the tasks. Keytool is a Java utility to manage a keystore (database) of private keys, certificate chains and trusted certificates. It is included in the Java distribution.

  1. Generating a keystore

    A keystore is a password protected file that stores the server’s private key and the certificate chain. A single keystore can contain multiple private keys and their corresponding certificate chains.

        ubuntu@ip-112-31-13-157:~$ keytool -genkey -alias abc -keyalg RSA -keysize 2048 -keystore /home/ubuntu/abc-keystore
        Enter keystore password:  abcdefghij12
        Re-enter new password: abcdefghij12
        What is your first and last name?
          [Unknown]:  www.mycompany.com
        What is the name of your organizational unit?
          [Unknown]:  mycompany
        What is the name of your organization?
          [Unknown]:  gecko
        What is the name of your City or Locality?
          [Unknown]:  Boston
        What is the name of your State or Province?
          [Unknown]:  Massachussets
        What is the two-letter country code for this unit?
          [Unknown]:  US
        Is CN=www.mycompany.com, OU=mycompany, O=gecko, L=Boston, ST=Massachussets, C=US correct?
          [no]:  yes
        Enter key password for <abc>
            (RETURN if same as keystore password): RETURN
    

    Note: It is important to hit RETURN when Keytool asks you set the key password. This will cause Keytool to set the key password to a value equivalent to the keystore password. Matching passwords are REQUIRED for Tomcat to access the certificate. If you choose two different passwords, any attempts to access the keystore will result in a crash (so don’t do it). Original Source.

  2. Generating a CSR
    ubuntu@ip-112-31-13-157:~$ keytool -certreq -keyalg RSA -keysize 2048 -alias abc -file mycompany.csr -keystore /home/ubuntu/abc-keystore
  3. Getting an SSL Certificate from a Certificate Authority using the generated CSR

    You will need to submit the CSR to a Certificate Authority so that they can generate your SSL certificate. Depending on the kind of certificate purchased and the level of trust sought, a domain name verification, business entity vertification etc. would be required. For our purpose, we settled for a domain name verification by creating a TXT record with the details provided by the CA. The TXT record creation was achieved by logging into our account with our domain name registrar.

  4. Downloading the SSL Certificates including the Root, Intermediate Certificates of your Certificate Authority (in our case Go Daddy).

    If everything goes smoothly, the SSL certificate should be available for download. Log into your account with the CA and download the SSL certificate. Along with the SSL certificate, you will need to download the Root certificate and all the intermediate certificates that establish the trust chain from your SSL certificate right up to your CA’s Root certificate.

  5. Importing Certificates into the Keystore

    The certificates need to be imported in an order to establish the trust chain starting with the Root certificate of your CA and then the next intermediate certificate and so on and so forth. Lastly your SSL certificate should be imported. Certificates should be imported into keystore in this order: root -> intermed -> purchased

        ubuntu@ip-112-31-13-157:~$ keytool -import -alias root -keystore abc-keystore -trustcacerts -file gdroot-g2.crt
        ubuntu@ip-112-31-13-157:~$ keytool -import -alias intermed -keystore abc-keystore -trustcacerts -file gdig2.crt 
        ubuntu@ip-112-31-13-157:~$ keytool -import -alias abc -keystore abc-keystore -trustcacerts -file 4af931ac9e4c59.crt 
    

    Note: The last import i.e. your SSL certificate import should have the same alias as the private key. Only then will it be mapped with the private key which is REQUIRED.

    If the import goes correctly, you can use the following command to check your SSL certificate’s trust chain

            ubuntu@ip-112-31-13-157:~$ openssl s_client -connect mycompany.com:443 -showcerts 
            CONNECTED(00000003)
            depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
            verify error:num=19:self signed certificate in certificate chain
            verify return:0
            ---
            Certificate chain
            0 s:/OU=Domain Control Validated/CN=www.mycompany.com
              i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate
              Authority - G2
            -----BEGIN CERTIFICATE-----
            Certificate data goes here
            -----END CERTIFICATE-----
            1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
              i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
            -----BEGIN CERTIFICATE-----
            Certificate data goes here
            -----END CERTIFICATE-----
            2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
              i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
            -----BEGIN CERTIFICATE-----
            Certificate data goes here
            -----END CERTIFICATE-----
            ---
            Server certificate
            subject=/OU=Domain Control Validated/CN=www.mycompany.com
            issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate
            Authority - G2
            ---
            No client certificate CA names sent
            ---
            SSL handshake has read 4270 bytes and written 391 bytes
            ---
            New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
            Server public key is 2048 bit
            Secure Renegotiation IS supported
            Compression: NONE
            Expansion: NONE
            SSL-Session:
                Protocol  : TLSv1
                Cipher    : DHE-RSA-AES256-SHA
                Session-ID: 539DF3DF95C4770DD748F2BEEDA7676E245E0E11DFAF11AC86F2530A9B32304A
                Session-ID-ctx: 
                Master-Key: 3B213B5D1D28299A6C6F35CA38185185F189E0873D2D5496FCF04FD17A30AD395DDA214E5B9587F24DCA73F011E83BDF
                Key-Arg   : None
                PSK identity: None
                PSK identity hint: None
                SRP username: None
                Start Time: 1402860511
                Timeout   : 300 (sec)
                Verify return code: 19 (self signed certificate in certificate chain)
            ---
        

    Verify return code: 19 (self signed certificate in certificate chain) is seen because the Root certificate is always self-signed. Root certificates are only issued by a handful of trusted Certificate Authorities and are trusted by browsers by default.

  6. Setting up Tomcat7 to use https

    You will need to edit the $CATALINA_BASE/conf/server.xml file. Locate the bit that looks like

            <!-- Define a SSL HTTP/1.1 Connector on port 8443
                This connector uses the JSSE configuration, when using APR, the
                connector should be using the OpenSSL style configuration
                described in the APR documentation 
            -->
    
            <!--
                <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                maxThreads="150" scheme="https" secure="true"
                clientAuth="false" sslProtocol="TLS"/>
            -->
        

    and change it to

          <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
              maxThreads="150" scheme="https" secure="true" keystoreFile="/home/ubuntu/abc-keystore" keyAlias="abc"
              keystorePass="abcdefghij12" keyPass="abcdefghij12" clientAuth="false" sslProtocol="TLS" />
        

    Note

    • You can choose between JSSE and APR which are two different implementations of SSL. When Tomcat is used as a standalone server, APR is recommended but it requires some additional libraries to be installed. Tomcat uses JSSE by default.
    • You can also choose to limit the usage of SSL on a webapp or url-scheme basis.
  7. Verification in the browser

    If things have gone smoothly, you should able to load your website using https://yourhost.com. To examine the certificate chain, click on the lock icon in your browser’s address bar and dig around, you should able to see your SSL certificate details as well as the entire trust chain that you set up while while importing the Root, intermediate, SSL certificates into your keystore.

Related Readings:
Certificate Chaining, Java Keytool and SSL