How do I make JBoss EAP/Tomcat use FIPS 140-2 compliant cryptography?
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
-
Enable the SunPKCS11 provider by adding the following line to the provider list in
$JAVA_HOME/jre/lib/security/java.securityand 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.cfgIf you are using JDK11, the line should be:
security.provider.1=SunPKCS11 /path/to/nss_pkcs11_fips.cfgAlso, change this line:
security.provider.5=com.sun.net.ssl.internal.ssl.Providerto this:
security.provider.5=com.sun.net.ssl.internal.ssl.Provider SunPKCS11-nss-fips -
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 = fipsNote: for 64 bit RHEL set the nssLibraryDirector to /usr/lib64
-
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 -
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 -
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 -
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 -
Configure the SSL connector to use the PKCS11 keystore
a. EAP 4.x and 5.x - Set the
keystoreTypeto PKCS11,keystorePass(must match the password set in step 5) andciphersin theserver.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-typeto PKCS11,password(must match the password set in step 5) andcipher-suitein thestandalone.xmlfile<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.xmlconfiguration file located in$JWS_HOME/tomcatX/conf/server.xmlfor JBoss Web Server (replace theXwith 6, 7, or 8; whatever your Tomcat version is) or change the file/etc/tomcat/server.xmlfor 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"/> -
To disable SSLv3, add SunPKCS11-nss-fips provider for com.sun.net.ssl.internal.ssl.Provider in
$JAVA_HOME/jre/lib/security/java.securitysecurity.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.
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.