tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicolas Therrien <>
Subject RE: Trying to understand How Tomcat uses Keystore for SSL
Date Tue, 14 Nov 2017 21:40:35 GMT
-----Original Message-----
From: Don Flinn [] 
Sent: Tuesday, November 14, 2017 1:58 AM
To: Tomcat Users List <>
Subject: Trying to understand How Tomcat uses Keystore for SSL

I've done some reading on SSL and understand the protocol is as follows; Client/Browser sends
ClientHello and server Tomcat replies with ServerHello.  This establishes the protocol they
will use.
The server then sends the certificate and the public key - in the clear The browser encrypts
a message containing the servers domain, all encrypted with the server's public key to the
CA which the browser trusts.  The public key is in the certificate.
The CA de-crypts the message with the server's private key.  So the server's name/ domain
must be not encrypted. If the server can decrypt the message it knows the server and it then
sends a ack message back to the browser encrypted with the client's private key.
The browser and Tomcat then establish a secret key to send messages back and forth.

If I have the above correct, I must have keystore set up incorrectly, since running my scenario
I get an error in the Chrome debugger,which says

This page is not secure
"Valid certificate
The connection to this site is using a valid, trusted server certificate issued by unknown
Secure resources
All resources on this page are served securely. "

Note the 'the certificate is valid and it is issued by unknown name"  Why is the issuer unknown,
since the issuer's name is in the certificate?

letsencrypt has an online web site from which one can download a ca_bundle, a private key
and a certificate for your domain Oracle has an article on keytool which says that keytool
 can not create a
pkcs12 keystore but can read it and to use openssl, which I did following their instructions.
 Concatenate the CA cert, the private key and the user cert then put these in keystore. The
result is shown below.  Tomcat isn't able to use this keystore to communicate with the browser
for some reason.
Why? What's missing or incorrect?

C:\Users\don\Security\letsenc>%keytool% -list -keystore MMcert.p12 -v -storetype pkcs12
Enter keystore password:

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

Alias name: tomcat
Creation date: Nov 13, 2017
Entry type: PrivateKeyEntry
Certificate chain length: 1
Issuer: CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US Serial number: 415913da3a6a956ef3efef2fb2eb4baff17
Valid from: Sat Nov 11 16:05:35 EST 2017 until: Fri Feb 09 16:05:35 EST 2018 Certificate fingerprints:
         MD5:  F5:FD:4F:8B:9A:A0:38:D1:B7:78:B6:36:38:AB:42:31
         SHA1: 7C:AB:5C:D3:A9:95:01:FD:43:CC:F5:D5:1D:24:64:1A:BF:4C:AE:66
         Signature algorithm name: SHA256withRSA
         Version: 3


#1: ObjectId: Criticality=false AuthorityInfoAccess [
   accessMethod: ocsp
   accessLocation: URIName:
   accessMethod: caIssuers
   accessLocation: URIName:

#2: ObjectId: Criticality=false AuthorityKeyIdentifier [ KeyIdentifier [
0000: A8 4A 6A 63 04 7D DD BA   E6 D1 39 B7 A6 45 65 EF  .Jjc......9..Ee.
0010: F3 A8 EC A1                                        ....

#3: ObjectId: Criticality=true BasicConstraints:[
  PathLen: undefined

#4: ObjectId: Criticality=false CertificatePolicies [
  [CertificatePolicyId: [] []  ]
  [CertificatePolicyId: []
[PolicyQualifierInfo: [
  qualifier: 0000: 16 1A 68 74 74 70 3A 2F   2F 63 70 73 2E 6C 65 74  ..
0010: 73 65 6E 63 72 79 70 74   2E 6F 72 67    

], PolicyQualifierInfo: [
  qualifier: 0000: 30 81 9E 0C 81 9B 54 68   69 73 20 43 65 72 74 69
0.....This Certi
0010: 66 69 63 61 74 65 20 6D   61 79 20 6F 6E 6C 79 20  ficate may only
0020: 62 65 20 72 65 6C 69 65   64 20 75 70 6F 6E 20 62  be relied upon b
0030: 79 20 52 65 6C 79 69 6E   67 20 50 61 72 74 69 65  y Relying Partie
0040: 73 20 61 6E 64 20 6F 6E   6C 79 20 69 6E 20 61 63  s and only in ac
0050: 63 6F 72 64 61 6E 63 65   20 77 69 74 68 20 74 68  cordance with th
0060: 65 20 43 65 72 74 69 66   69 63 61 74 65 20 50 6F  e Certificate Po
0070: 6C 69 63 79 20 66 6F 75   6E 64 20 61 74 20 68 74  licy found at ht
0080: 74 70 73 3A 2F 2F 6C 65   74 73 65 6E 63 72 79 70  tps://letsencryp
0090: 74 2E 6F 72 67 2F 72 65   70 6F 73 69 74 6F 72 79
00A0: 2F                                                 /

]]  ]

#5: ObjectId: Criticality=false ExtendedKeyUsages [

#6: ObjectId: Criticality=true KeyUsage [

#7: ObjectId: Criticality=false SubjectAlternativeName [

#8: ObjectId: Criticality=false SubjectKeyIdentifier [ KeyIdentifier [
0000: 04 6B 27 5C F4 5E 85 21   24 38 A7 44 2D 7E 69 CA  .k'\.^.!$8.D-.i.
0010: CF 31 04 1C                                        .1..



Hi Don,

I think I can help you move forward, but just so you know, I am not an official Tomcat developer.
Just a mailing list member who once got help here and now giving back :)

I think your understanding of how the SSL Handshake is incorrect.   In particular, the way
you depicted the CA's role in an SSL handshake is incorrect.    The CA is never involved in
SSL Handshakes.     SSL connections are between you and the server, always. There is no third
party, and we certainly do not want one!    There are plenty of resources to explain SSL Handshake
( I like the page published on IBM's Knowledge Center:
but I'll summarize it here for you.

Browser sends ClientHello with a list of cipher suites it can support.
Server responds with a cipher suite selection and a digital certificate (which also contains
a public key).

So far so good.

Now, how does the Browser validates that it is communicating with the right/genuine server
it was trying to contact? What proof do we have that it is not a usurper?

Browser takes the certificate and does this:

1) Is this certificate cryptographically signed by someone I trust?    Your computer already
contains a list of CA public keys that can be used to validate that a given certificate signature
is valid.    Keep in mind a certificate may be signed by more than one CA, which is why we
often talk of a certificate chain.    There only needs to be one signature in that chain that
your computer recognizes for this server certificate to be deemed valid.

Is that enough to validate that the certificate is valid though?    Like a passport, the fact
that is genuine and delivered by your government is important, but for the customs office
to accept it, it must be YOURS!  So that's why there's step two:

2) Is this certificate delivered for the domain name I was trying to access?   (is this passport
in your name?)

If those two critera are met, then the certificate verification is going to succeed and the
ssl handshake will move on to the next step which is to start the encrypted session.

Here comes problem #2: asymmetrical encryption (such as public key encryption) is a ONE WAY
communication channel.  While anyone with a public key can encrypt data, ONLY the owner of
the private key will be able to decrypt. And a private key is... well... secret!! Only  the
server has it.  So there's no way the client could decrypt whatever the server would say.

THAT's why the browser will generate a symmetrical session encryption key. A key that will
be used by both the client and server to encrypt data in both directions.  And in order to
protect that key from being intercepted, we must not send it in the clear.   We will use the
server's one-way public key to encrypt that symmetrical encryption key and send it to the

Only with the session key installed on both sides, does the encrypted session begin.

This concludes the summary which I hope will help you understand the handshake part.

Now I understand your ultimate goal is to get rid of warnings and get that little green lock
on your browser.

Assuming you have obtained a valid signed certificate from LetsEncrypt, here's what you have
to do.

Step 1:
Start using KeyStore Explorer.   It's so much easier to use a GUI than the command line :P

Step 2:
You mentioned that LetsEncrypt gave you a keystore with a private key in it.   I'm going to
assume they gave you a package which contains a private key and a certificate, and that the
point was to simplify the process of generating a CSR (Certificate Signing Request).

Just know that the fact that the private key was given to you by a third party is a potential
security risk to your own security. 

The NORMAL process is to generate your own private key, generate a CSR, send LetsEncrypt the
CSR, obtain a Signed CSR and re-import into your keystore.    That has maximum security.

Step 3:
Make a copy of your original keystore file.    Then you can open your keystore with Keystore
Explorer and change its format to JKS.    Super easy.    I think its under the tool menu.
  You can rename your keystore file so that it ends in *.jks   (make sure you saved the keystore
using the save button!)

Step 4:
Copy that jks file to your server under the conf folder of tomcat.

Step 4:
In your Tomcat server.xml file you need something like this:

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig protocols="TLSv1.2">
            <Certificate certificateKeystoreFile="localhost.keystore.jks"
                         certificateKeyAlias="alias" />

The alias is just a name used to designate a given certificate in case there are more than
one in your keystore. Just a good habit to be specific.   You can find what is the alias name
for your certificate using Keystore Explorer

VoilĂ !

That should give you a valid SSL configuration on your server.  If you still get an issue
with Chrome warnings, this means the certificate contained in the keystore is not signed properly.
You can easily check if a certificate is signed using the Keystore Explorer and right-clicking
then view details... see certificate chain.    In that chain, you should be able to see some
top CA authority signing your cert. If none of those CAs in the chain are approved by chrome,
it wont work.  You'll need to find another provider.


- Nicolas

View raw message