tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Don Flinn <fl...@alum.mit.edu>
Subject Re: Trying to understand How Tomcat uses Keystore for SSL
Date Mon, 04 Dec 2017 03:07:29 GMT
Thanks Chuck

In plain text

Please comment on the following write-up.

Setting Up SSL for TomCat
1) Overview of Security for Tomcat

Security is hard, which by extension means setting up SSL is hard.   One of
the things that make this difficult is that there are multiple layers of
specifications.  In this explanation we are only go as deep into the
technical description as is necessary for you to understand what is going
on.

At the bottom layer of security is cryptography, which is based on
encryption.  We won’t go into encryption except to say that all encryption
protocols are breakable, except the One Time Pad, which is impracticable.
The principal of computer security is to make it very difficult to break
the encryption.  Using a modern desktop computer it would take a little
over 6.4 quadrillion years to crack the encryption of a 2048 bit RSA
certificate.  Note: practical quantum computers large enough to negate this
time estimate don't exist, yet

There are two encryption schemes that are of interest, asymmetric and
symmetric encryption.  Asymmetric encryption uses a public and a private
encryption key.  The public key, which as its name states, is public, i.e.
it is available to all. The private key is and must be closely guarded.  A
message encrypted with the private key can be decrypted by the public key
and vis-a-versa.

SSL or Secure Sockets Layer, is the high level security layer that we are
attempting to implement for for our implementation of Tomcat.  SSL uses
both asymmetric and symmetric encryption, but at the level we are
interested in we only deal with the former, while Tomcat and the other
parties like the browser deal with both.

In the scenario that we are addressing there are three parties involved
* your installation of Tomcat
* the browser with whom you wish to communicate and
* the Certificate Authority or CA, e.g. letsencrypt, Comodo, etc.

In cryptography, a certificate authority or certification authority (CA) is
an entity that issues digital certificates. A digital certificate certifies
the ownership of a public key by the named subject of the certificate. This
allows others (relying parties) to rely upon signatures or on assertions
made about the private key that corresponds to the certified public key. A
CA acts as a trusted third party—trusted both by the subject (owner) of the
certificate and by the party relying upon the certificate. The format of
these certificates is specified by the X.509 standard.

In order to set up SSL, you want to get a private/public key pair and what
is called a Security Certificate or more properly, an X509 certificate.
The Security Certificate contains information about who you are and is
attested to by the CA, whom the browser trusts.  In some cases, like the CA
letsencrypt, the trust of the CA by all browser is not yet there, so the
certificate contains an intermediate CA whom the browsers trust and who
attests for the CA who trusts your domain.  Each of the CA's, the root CA,
who trusts us and intermediate who trusts the root CA, digitally sign
(another specification) the certificate with their private keys, so that
the browsers and other interested parties can verify the subject of the
certificate. This is accomplished by using the CA's public key to assure
that this certificate was signed by the root or intermediate CA with their
private key.

The certificates and keys have specified binary structures so that they can
be machine read.  This structure is defined by using an abstract notation
called ASN.1, Abstract Syntax Notation One, which defines data types in a
binary format.  A subset of ASN.1, BER defines how to encode each value
type.  BER has more than one way to encode a data type, so there is DER,
which gives a unique encoding to each of the BER data types.

A DER encoded certificate is an encoded binary form of the certificate.
Binary data can not be sent over the internet, so for transportation they
are base64 encoded, which transforms the binary bits into ASCII, which can
then be sent over the internet.  Note base64 is not human readable but is
NOT encryption.  Encoding and decoding can be done using a well known
algorithm.  In essence PEM files are just base64 encoded versions of the
DER encoded data.

Before we leave this section there is another distinction.  We use the term
SSL, Secure Sockets Layer.  SSL has been replaced by TLS, Transport Layer
Security.  TLS is more secure than SSL, which is affectedly dead.  The bad
guys are continually working to break security, whereas the good guys are
working to beat the bad guys.  Consequently, for a secure system you must
continually upgrade to the latest security protocols.
2) How to Create and See what You Have
There is an open source set of commands called openssl which will allow you
to look inside the various certificates and keys that you have as well as
other functionality.   You can download openssl at
https://www.openssl.org/source/ .   Openssl comes as a set of command line
functions and an API.

Some of the common openssl commands that you might use are (reproduced from
GitHub):

#### Generate RSA private key (2048 bit)
    openssl genrsa -out private.pem 2048

#### Generate a Certificate Signing Request (CSR)
    openssl req -sha256 -new -key private.pem -out csr.pem

#### Generate RSA private key (2048 bit) and a Certificate Signing Request
(CSR) with a single command
    openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out
server.csr

#### Convert private key to PEM format
    openssl rsa -in server.key -outform PEM -out server.pem

#### Generate a self-signed certificate that is valid for a year with
sha256 hash
    openssl x509 -req -sha256 -days 365 -in csr.pem -signkey private.pem
-out certificate.pem

#### View details of a RSA private key
    openssl rsa -in private.pem -text -noout

#### View details of a CSR
    openssl req -in csr.pem -text -noout

#### View details of a Certificate
    openssl x509 -in certificate.pem -text -noout

#### View details of a Certificate in DER format
    openssl x509 -inform der -in certificate.cer -text -noout

#### Convert a DER file (.crt .cer .der) to PEM
    openssl x509 -inform der -in certificate.cer -out certificate.pem

#### Convert a PEM file to DER
    openssl x509 -outform der -in certificate.pem -out certificate.cer
An example of using an openssl command against a certificate such as the
following:

-----BEGIN CERTIFICATE-----
MIIFAzCCA+ugAwIBAgISA+3lA2/GXmArkvSKMxVexUebMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzExMjYwNDM2MDBaFw0x
     <more data>

-----END CERTIFICATE-----

Running the openssl command
openssl x509 -in <certificate file> -text -noout
displays information such as the following abbreviated output:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            03:ed:e5:03:6f:c6:5e:60:2b:92:f4:8a:33:15:5e:c5:47:9b
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3
        Validity
            Not Before: Nov 26 04:36:00 2017 GMT
            Not After : Feb 24 04:36:00 2018 GMT
        Subject: CN=<your domain>
        Subject Public Key Info:

<skipped data>

         Authority Information Access:
             OCSP - URI:http://ocsp.int-x3.letsencrypt.org
             CA Issuers - URI:http://cert.int-x3.letsencrypt.org/

         X509v3 Subject Alternative Name:
             DNS:<your domain name>
         X509v3 Certificate Policies:
             Policy: 2.23.140.1.2.1
             Policy: 1.3.6.1.4.1.44947.1.1.1
               CPS: http://cps.letsencrypt.org
               User Notice:
                 Explicit Text: This Certificate may only be relied upon by
Rely

 Signature Algorithm: sha256WithRSAEncryption
<skipped signature information>

Looking at the above you can see that the certificate contains
* the public key;
* who issued the certificate;
* to whom the certificate was issued,
* <your domain>;
* when the certificate is valid and
* the digital signature of the certificate.  (Yet another specification)

There is another tool that comes with your java implementation called
keystore.  The java keystore is installed with your implementation of
Java.  Specifically, the jdk<version>/bin directory contains an executable
called keytool.  Using keytool you can construct a file database called
keystore and operate on and use that database for setting up SSL for
Tomcat.

For example, common keytool commands are:
* Generate a Java keystore and key pair
keytool -genkey -alias mydomain -keyalg RSA -keystore keystore.jks -keysize
2048
* Generate a certificate signing request (CSR) for an existing Java keystore
keytool -certreq -alias mydomain -keystore keystore.jks -file mydomain.csr
* Import a root or intermediate CA certificate to an existing Java keystore
keytool -import -trustcacerts -alias root -file Thawte.crt -keystore
keystore.jks
* Import a signed primary certificate to an existing Java keystore
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)
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks
-storepass password -validity 360 -keysize 2048
* Check a stand-alone certificate
keytool -printcert -v -file mydomain.crt
* Check which certificates are in a Java keystore
keytool -list -v -keystore keystore.jks
* Check a particular keystore entry using an alias
keytool -list -v -keystore keystore.jks -alias mydomain
* Delete a certificate from a Java Keytool keystore
keytool -delete -alias mydomain -keystore keystore.jks
* Change a Java keystore password
keytool -storepasswd -new new_storepass -keystore keystore.jks
* Export a certificate from a keystore
keytool -export -alias mydomain -file mydomain.crt -keystore keystore.jks
* List Trusted CA Certs
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
* Import New CA into Trusted Certs
keytool -import -trustcacerts -file /path/to/ca/ca.pem -alias CA_ALIAS
-keystore $JAVA_HOME/jre/lib/security/cacerts

3) Trust

There are various levels of trust – Browsers trust certain CAs, the CAs
trust various domains and you trust certain CAs.

All browsers contain a list of CAs with whom they have established trust.
You can examine this list by reading the documentation of a particular
browser.  This trust establishment is between the browser and the CA.  You,
in turn, trust that the browser has indeed faithfully established that
trust.

The CA establishes trust in your domain.  Different CAs use different
methods for establishing that trust and charge you depending on the the
method of establishing that trust.  For example letsencrypt certificates
are free whereas Verisign Secure Site Pro costs $1,199 per year.  Note:
Semantic bought Verisign's identity and authentication security business.
Chrome plans to drop Semantic certificates in 2018.  Again, keep aware of
what is happening in the security world.   Its up to you to establish and
maintain trust in the CA you choose.

Some CAs use an intermediate CA, which is trusted by the browser to cross
sign their certificates.  In this case the browser trusts the intermediate
and the intermediate trusts your CA, who trusts your domain.  The
establishment of the browser CA trust is out of your control, with the
caution that you keep up with the literature and reports on these
relationships as noted above.

CAs use various means of establishing trust in your domain, from personal
inspection to some digital check, to confirm that you have legitimate
control of the domain and charge you accordingly.

4) Obtaining the Certificate

There are three steps in obtaining a certificate
1. Create a public private key pair
2. Create and send a request to the CA, called a Certificate Signing
Request or CSR
3. Prove to the CA that you own/control domain for the request

You create the key pair using openssl or using the java keystore as shown
in the commands above.  You then create a CSR and digitally sign it with
your private key.  The CSR contains information about your company and your
public key.  The CSR may also contain other information to prove your
identity and/or the CA may contact you for further information.  For
example, letsencrypt sends you a unique token which you place in <your
domain>/.well-known/acme-challenge.  If letsencrypt can retrieve that
token, it is proof that you control the domain.  .The CA of your choice may
have tools that you can use to obtain a certificate.  Note that you must
make your domain available to a call to your domain.  Since the call will
be to port 80 and Tomcat normally runs on port 8080 you must transfer the
port 80 call to Tomcat.  One way is to set Tomcat to run on port 80.
Another way on Linux is to use iptables.  On windows use netsh.
Chrome’s distrust of Symantic’s Extended Value Certificates is based on
what Google called sloppiness in validating their clients when requesting
certificates.
5) Securing Tomcat

Once you have your certificate, you set up Tomcat to use that certificate.
Here you can use keystore or PKCS12.  In either case you want to import
your certificate chain as follows:
1. Your certificate
2. Intermediate certificates (if applicable)
3. Root certificate
Tomcat currently operates only on JKS, PKCS11 or PKCS12 format keystores.
The JKS format is Java's standard "Java KeyStore" format, and is the format
created by the keytool command-line utility. This tool is included in the
JDK. The PKCS12 format is an internet standard, and can be manipulated via
(among other things) OpenSSL and Microsoft's Key-Manager.
6) Using PKCS12
Using Tomcat greater than version 8.5 you can directly use the PKCS12 files
created by openssl.  First edit the <Catelina>/config/server.xml> as
follows:
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeyFile= “<path to your key file>
certificateFile=<path to your domain-chain.crt >
certificateChainFile=<path to the root.crt >
type="RSA" />
</SSLHostConfig>
</Connector>
The domain-chain.crt is that returned by your CA.  Use openssl to examine
what is in the domain-chain.crt.   First cat the file to see how many
certificates it contains.   You can identify a certificate by the opening
clear text -----BEGIN CERTIFICATE----- and the end by -----END
CERTIFICATE----- with base64 data encoded data in between.  If you have
more than one certificate run the openssl command as described above in the
section How to Create on each certificate to see what it contains.  If
there is a second certificate it may contain the intermediate information.
As for the root certificate, the CA may download it to you as part of the
response to the csr or you may have to get it separately from the CA’s
site.  The CA document will tell you what you should get.

You will also have to edit web.xnl as follows:
Edit web.xml
Add a security-constraint to web.xml for the subdirectories that you wish
to protect with SSS.
<web-app>
  ...
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>Subdirectories you wish to
protect</web-resource-name>
        <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>
</web-app>
The url-pattern in the example means all the directories under the
subdirectories in webapps chosen for protection. Setting the transport-
guarantee to NONE turns off security.
7) Using keystore
Each entry in a keystore is identified by an alias string. While many
keystore implementations treat aliases in a case insensitive manner, case
sensitive implementations are available. The PKCS11 specification, for
example, requires that aliases are case sensitive. To avoid issues related
to the case sensitivity of aliases, it is not recommended to use aliases
that differ only in case.
Use the JKS format create a keystore as follows:
keytool -import -trustcacerts -alias mydomain -file mydomain.crt -keystore
keystore.jks
keytool -import -trustcacerts -alias root -file <intermediate crt)
-keystore keystore.jks  (if applicable and may be multiple intermediates)
keytool -import -trustcacerts -alias root -file (root.crt) -keystore
keystore.jks
8) Edit the Tomcat Configuration File
Tomcat can use three different implementations of SSL:
* JSSE implementation provided as part of the Java runtime
* JSSE implementation that uses OpenSSL
* APR implementation, which uses the OpenSSL engine by default
The exact configuration details depend on which implementation is being
used. If you configured Connector by specifying generic
protocol="HTTP/1.1"then the implementation used by Tomcat is chosen
automatically. If the installation uses APR - i.e. you have installed the
Tomcat native library - then it will use the JSSE OpenSSL implementation,
otherwise it will use the Java JSSE implementation.
Auto-selection of implementation can be avoided if needed. It is done by
specifying a classname in the protocol attribute of the Connector.
To define a Java (JSSE) connector, regardless of whether the APR library is
loaded or not, use one of the following:
<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO implementation -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"

 sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
           port="8443" .../>

<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO2 implementation -->
<Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"

 sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
           port="8443" .../>
The OpenSSL JSSE implementation can also be configured explicitly if
needed. If the APR library is installed (as for using the APR connector),
using the sslImplementationName attribute allows enabling it. When using
the OpenSSL JSSE implementation, the configuration can use either the JSSE
attributes or the OpenSSL attributes (as used for the APR connector), but
must not mix attributes from both types in the same SSLHostConfig or
Connector element.
<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO implementation and
OpenSSL -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443"

 sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
           .../>
Alternatively, to specify an APR connector (the APR library must be
available) use:
<!-- Define a HTTP/1.1 Connector on port 8443, APR implementation -->
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
           port="8443" .../>
If you are using APR or JSSE OpenSSL, you have the option of configuring an
alternative engine to OpenSSL.
<Listener className="org.apache.catalina.core.AprLifecycleListener"
          SSLEngine="someengine" SSLRandomSeed="somedevice" />
The default value is
<Listener className="org.apache.catalina.core.AprLifecycleListener"
          SSLEngine="on" SSLRandomSeed="builtin" />
Also the useAprConnector attribute may be used to have Tomcat default to
using the APR connector rather than the NIO connector:
<Listener className="org.apache.catalina.core.AprLifecycleListener"
          useAprConnector="true" SSLEngine="on" SSLRandomSeed="builtin" />
So to enable OpenSSL, make sure the SSLEngine attribute is set to something
other than off. The default value is on and if you specify another value,
it has to be a valid OpenSSL engine name.
SSLRandomSeed allows specifying a source of entropy. Productive system
needs a reliable source of entropy but entropy may need a lot of time to be
collected therefore test systems could use no blocking entropy sources like
"/dev/urandom" that will allow quicker starts of Tomcat.
The final step is to configure two files  in Tomcat - the Connector in the
$CATALINA_BASE/conf/server.xml file, where $CATALINA_BASE represents the
base directory for the Tomcat instance and the web.xml file.  An example
<Connector> element for an SSL connector is included in the default
server.xml file installed with Tomcat. To configure an SSL connector that
uses JSSE, you will need to remove the comments and edit it so it looks
something like this:
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="${user.home}/.keystore" keystorePass="changeit"
           clientAuth="false" sslProtocol="TLS"/>
Note: If tomcat-native is installed, the configuration will use JSSE with
an OpenSSL implementation, which supports either this configuration or the
APR configuration example given below.
The APR connector uses different attributes for many SSL settings,
particularly keys and certificates. An example of an APR configuration is:
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector
           protocol="org.apache.coyote.http11.Http11AprProtocol"
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           SSLCertificateFile="/usr/local/ssl/server.crt"
           SSLCertificateKeyFile="/usr/local/ssl/server.pem"
           SSLVerifyClient="optional" SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"/>
The configuration options and information on which attributes are
mandatory, are documented in the SSL Support section of the HTTP
connectorconfiguration reference. Make sure that you use the correct
attributes for the connector you are using. The NIO and NIO2 connectors use
JSSE unless the JSSE OpenSSL implementation is installed (in which case it
supports either the JSSE or OpenSSL configuration styles), whereas the
APR/native connector uses APR.
The port attribute is the TCP/IP port number on which Tomcat will listen
for secure connections. You can change this to any port number you wish
(such as to the default port for https communications, which is 443).
However, special setup (outside the scope of this document) is necessary to
run Tomcat on port numbers lower than 1024 on many operating systems.
If you change the port number here, you should also change the value
specified for the redirectPort attribute on the non-SSL connector. This
allows Tomcat to automatically redirect users who attempt to access a page
with a security constraint specifying that SSL is required, as required by
the Servlet Specification.
After completing these configuration changes, you must restart Tomcat as
you normally do, and you should be in business. You should be able to
access any web application supported by Tomcat via SSL. For example, try:
https://localhost:8443/
and you should see the usual Tomcat splash page (unless you have modified
the ROOT web application). If this does not work, the following section
contains some troubleshooting tips.
Edit web.xml as described above.
9) Installing a Certificate from a Certificate Authority
To obtain and install a Certificate from a Certificate Authority (like
verisign.com, thawte.com or trustcenter.de), read the previous section and
then follow these instructions:
10) Create a local Certificate Signing Request (CSR)

In order to obtain a Certificate from the Certificate Authority of your
choice you have to create a Certificate Signing Request (CSR). That CSR
will be used by the Certificate Authority to create a Certificate that will
identify your website as "secure". To create a CSR follow these steps:
* Create a local self-signed Certificate (as described in the previous
section):
* keytool -genkey -alias tomcat -keyalg RSA
    -keystore <your_keystore_filename>
Note: In some cases you will have to enter the domain of your website (i.e.
www.myside.org) in the field "first- and lastname" in order to create a
working Certificate.
* The CSR is then created with:
* keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr
    -keystore <your_keystore_filename>
Now you have a file called certreq.csr that you can submit to the
Certificate Authority (look at the documentation of the Certificate
Authority website on how to do this). In return you get a Certificate.
11) Importing the Certificate
Now that you have your Certificate you can import it into you local
keystore. First of all you have to import a so called Chain Certificate or
Root Certificate into your keystore. After that you can proceed with
importing your Certificate.
* Download a Chain Certificate from the Certificate Authority you obtained
the Certificate from.
For Verisign.com commercial certificates go to:
http://www.verisign.com/support/install/intermediate.html
For Verisign.com trial certificates go to:
http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.html
For Trustcenter.de go to:
http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
For Thawte.com go to: http://www.thawte.com/certs/trustmap.html
* Import the Chain Certificate into your keystore
* keytool -import -alias root -keystore <your_keystore_filename>
    -trustcacerts -file <filename_of_the_chain_certificate>
* And finally import your new Certificate
* keytool -import -alias tomcat -keystore <your_keystore_filename>
    -file <your_certificate_filename>

Restart Tomcat and run a test case.

12) References

Applied Cryptography (Second Edition) Bruce Schneier 1996
Old but still a great book for learning the details of cryptography. Long
at 758 pages

A Layman's Guide to a Subset of ASN.1, BER, and DER  Burton S. Kaliski Jr.
Revised November 1, 1993 http://luca.ntop.org/Teaching/Appunti/asn1.html
A layman's introduction to a subset of OSI's Abstract Syntax Notation One
(ASN.1), Basic Encoding Rules (BER), and Distinguished Encoding Rules (DER).

Festy Duck OpenSSL Cookbook by Ivan Risti?
https://www.feistyduck.com/library/openssl-cookbook/
Free download of a detailed description of all aspects of OpenSSL









On Sun, Dec 3, 2017 at 9:13 PM, Caldarale, Charles R <
Chuck.Caldarale@unisys.com> wrote:

> > From: Don Flinn [mailto:flinn@alum.mit.edu]
> > Subject: Re: Trying to understand How Tomcat uses Keystore for SSL
>
> > Attached is a first cut at setting up SSL for Tomcat.  It is in MicroSoft
> Word.
>
> Most attachments are automatically stripped by the mailing list server.
> You
> can either send it in plain text or post it somewhere publicly accessible.
>
>  - Chuck
>
>
> THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
> MATERIAL and is thus for use only by the intended recipient. If you
> received
> this in error, please contact the sender and delete the e-mail and its
> attachments from all computers.
>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message