How do I make JBoss EAP/Tomcat use FIPS 140-2 compliant cryptography?

Solution Verified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform
    • 4.x
    • 5.x
    • 6.x
  • Red Hat JBoss Web Server - Tomcat
    • 2.x
    • 3.x
  • OpenJDK
  • SunJDK

Issue

  • How do I make JBoss EAP FIPS 140-2 compliant?
  • How do I make Tomcat FIPS 140-2 compliant?
  • Is JBOSS EAP 6.2 FIPS 140-2 compliant?

Resolution

JBoss EAP and Tomcat cannot be FIPS 140-2 compliant themselves since they do not directly perform cryptography, but you can configure them to use FIPS 140-2 compliant cryptography modules.

Configuring JBoss EAP and Tomcat to use FIPS 140-2 compliant cryptography mostly involves changes at the JDK level in the java.security and your NSS cfg file. JBoss EAP and Tomcat have differing styles of configuration so this guide will split off into each specific product near the end.

  • Use the Mozilla NSS library in FIPS mode
  1. Enable the SunPKCS11 provider by adding the following line to the provider list in $JAVA_HOME/jre/lib/security/java.security and increment the provider numbers for the remaining providers. The path can be "${java.home}/lib/security/nss_pkcs11_fips.cfg" to keep the file in the same directory as the java.security policy file.

         security.provider.1=sun.security.pkcs11.SunPKCS11 /path/to/nss_pkcs11_fips.cfg
    

    If you are using JDK11, the line should be:

             security.provider.1=SunPKCS11 /path/to/nss_pkcs11_fips.cfg
    

    Also, change this line:

     security.provider.5=com.sun.net.ssl.internal.ssl.Provider
    

    to this:

     security.provider.5=com.sun.net.ssl.internal.ssl.Provider  SunPKCS11-nss-fips
    
  2. Create the NSS configuration file (nss_pkcs11_fips.cfg). The "/path/to/db" should be readable by all users who will be running java. The format of this file is described in http://docs.oracle.com/javase/6/docs/technotes/guides/security/p11guide.html.

         name = nss-fips
         nssLibraryDirectory = /usr/lib
         nssSecmodDirectory = /path/to/db
         nssDbMode = readOnly
         nssModule = fips
    

    Note: for 64 bit RHEL set the nssLibraryDirector to /usr/lib64

  3. Create the db in the location specified by nssSecmodDirectory setting defined above. Also, make sure that all users running java applications can read the NSS db files.

         mkdir -p /path/to/db
         modutil -create -dbdir /path/to/db
         chmod a+r /path/to/db/*.db            
    
  4. Enable FIPS mode for the NSS library.  If you get a security library error, you might need to regenerate the library signatures for some of the NSS shared objects (look for /usr/lib/libnss*.chk and then run shlibsign -v -i <name of the shared object>).

         modutil -fips true -dbdir /path/to/db
    
  5. Change password on the fips token.  Note that the password must be a FIPS compliant password. A FIPS compliant password must be at least seven characters in length and include characters from at least three of the following character classes: ASCII digits, lowercase ASCII, uppercase ASCII, non-alphanumeric ASCII, and non-ASCII. If an ASCII uppercase letter is the first character of the password/PIN, the uppercase letter is not counted toward its character class. Similarly, if a digit is the last character of the password/PIN, the digit is not counted toward its character class.

         modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /path/to/db
    
  6. Create a certificate using the NSS tools.

         certutil -S -k rsa -n jbossweb  -t "u,u,u" -x -s "CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, ST=MYSTATE, C=MY" -d /path/to/db
    
  7. Configure the SSL connector to use the PKCS11 keystore

    a. EAP 4.x and 5.x - Set the keystoreType to PKCS11, keystorePass (must match the password set in step 5) and ciphers in the server.xml

         <Connector port="8443" address="${jboss.bind.address}"                                         
                    protocol="HTTP/1.1" SSLEnabled="true"                                               
                    maxThreads="150" scheme="https" secure="true"                                       
                    clientAuth="false" sslProtocol="TLS"                                                
                    keystorePass="fips_compliant_password"                                                             
                    keystoreType="PKCS11" ciphers="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA,TLS_ECDH_anon_WITH_AES_256_CBC_SHA"/>
    

    b. EAP 6.x - Set the keystore-type to PKCS11, password (must match the password set in step 5) and cipher-suite in the standalone.xml file

         <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
           <ssl name="https" password="****" 
             cipher-suite="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA,TLS_ECDH_anon_WITH_AES_256_CBC_SHA"
             keystore-type="PKCS11"/>
         </connector>
    

    c. Tomcat - Configure a new connector or update your existing HTTPS Connector like below. These changes will be made in your server.xml configuration file located in $JWS_HOME/tomcatX/conf/server.xml for JBoss Web Server (replace the X with 6, 7, or 8; whatever your Tomcat version is) or change the file /etc/tomcat/server.xml for RHEL Tomcat.

         <Connector port="8443" protocol="HTTP/1.1"
               SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystorePass="fips_compliant_password"
               keystoreType="PKCS11"
               ciphers="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA,TLS_ECDH_anon_WITH_AES_256_CBC_SHA"/>
    
  8. To disable SSLv3, add SunPKCS11-nss-fips provider for com.sun.net.ssl.internal.ssl.Provider in $JAVA_HOME/jre/lib/security/java.security

     security.provider.5=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-nss-fips
    

Diagnostic Steps

Verify the JVM can read the private key from the PKCS11 keystore:

keytool -list -storetype pkcs11

If the keytool does not display the keys from the PKCS11 keystore, then the JVM is not setup properly.

Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.