Tuesday, December 17, 2013

Configure a FIPS 140-2 Compliant Java Provider on RedHat/CentOS/Fedora

If you're using any form of cryptography in Java, you might be aware of NIST FIPS 140-2, which lays out what you can and cannot use on federal information processing systems.

Oracle documentation, true to form, only gets you 80% of the way there.  Here's their technical notes on FIPS 140 compliance.

So here are the step-by-step instructions for configuring java with a FIPS-compliant Provider (SunPKCS11-NSS).

First, you need to install the libraries if you haven't already.  These are written by Mozilla, and have gone through NIST's Cryptographic Module Validation Program (CMVP).  Luckily, they're available for RedHat/CentOS/Fedora, and can be installed through yum.

sudo yum install nss-pkcs11-devel
 Next, you need to configure your JRE to add the provider.  You do this by editing ${jre.home}/lib/security/java.security and adding a reference to the SunPKCS11 provider.

On my Fedora 19 box, I have both the OpenJDK and SunJDK installed.  Here are the locations of their JREs on my box.

cd /usr/lib/jvm/java-1.7.0-openjdk-
sudo vim java.security
cd /usr/java/jdk1.7.0_15/jre/lib/security
sudo vim java.security
Be careful that you don't update one and then run your app on the other.  I just configured both and now I can run my apps on either.

Anyway, in the picture below, you'll notice that I've added:
security.provider.10=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/nss.cfg

In the same directory, edit (or create if it isn't there) your nss.cfg:
sudo vim nss.cfg
The only change I had to make to this file was to set 'nssLibraryDirectory' to /usr/lib64, which is where your libnss3.so library was installed when you ran 'yum install' earlier.

Now, you may use the SunPKCS11-NSS provider in your Java applications, which is FIPS-compliant.  Here's a tiny app that creates a java.security.Signature for creating digital signatures.  It is configured to use the SHA256withRSA algorithm via the SunPKCS11-NSS provider.
 This program just loads the Signature instance - it doesn't do anything with it.  If the program runs without printing a stack trace, then you've successfully configured Java with a FIPS-compliant provider.

You can compile and run your program thus:


  1. Hi John, Its very helpful! May I know if you can share how to enable Tomcact 7 FIPS compliant?

  2. I'm sorry, I don't know how you might do that.

  3. Hi John, I tried the above but still getting an error java.security.NoSuchProviderException: no such provider: .SunPKCS11-NSS. Any help on what could be the issue. I am doing this on CentOS 6.4.


    1. Pls ignore the provider name as configured wrongly. It is working.


  4. Thank you for sharing. Appreciate you for sharing the configuration example. It made my day.

  5. Hello,
    I don't think it's considered strictly fips compliant unless NSS is configured as such (either by setting "nssModule = fips" in the config file, or if secmod.db is set to be compliant, which will enable NSS fips compliance by default).

  6. Right Viviek, Above configuration is not at all FIPS compliant. The above configuration is just configuring cryptography provider as NSS. That's All.

    Please see http://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#NSS.