Solve technical challenges with BC-FIPS

Last week I talked about the requirements for implementing TLS and certified cryptographic modules (specifically Bouncy Castle FIPS or BC-FIPS). Today I'll get a little more technical about how to solve this problem and the specific technical challenges you may face.

First of all, BC-FIPS provides some installation instructions that a) no longer work in JDK-11 and b) do not play well with Spring Boot uber-jar class loading using the standard classpath override mechanism. I haven't found the root cause of this problem. All I did was load the BC-FIPS security module dynamically at application startup.

These (non-working) instructions include the necessary modifications to the JDK, specifically the file and the lib/ext folder.

There are three aspects to this configuration:

  1. Compliant SecureRandom generation (as described in the BC-FIPS document)
  2. Install BC FIPS Security Provider
  3. Install BC JSSE Security Provider

Do this in a static method before database initialization. This is because your DB initialization code must be able to obtain a FIPS-compliant socket factory to initialize the connection pool.

private revolution invalid reset() {
// Initialization required to use the BCFKS module.
security.insertProviderAt(new BouncyCastleFipsProvider(), 1);
security.insertProviderAt(new BouncyCastleJsseProvider(), 2);

* Created NIST SP 80090A compatible secure random number
* generator.
* @return Compatible generator.
private revolution SecureRandom getSecureRandom() {

*According to NIST Special Publication 800-90A, now is
* A time-varying value with negligible probability at best.
* Repetition (e.g. a new random value generated for each)
* use, timestampSequence number or combination of:
* these.
* now It is combined with the entropy input to generate the initial value.
* DRBG seed.
byte [] now = byte buffer.allocate(8).putLong(system.nano time()).Sort();
Entropy source provider ent source = new Default entropy source provider (new securityrandom(), truth);
FipsDRBG.Builder drgbBldr =FipsDRBG.SHA512
.fromentropysource(ent source).setsecurityStrength(256)
return, truth);

See also  Watch MEDITECH customers share how they are driving transformational change

The above code effectively accomplishes the task of changing your JDK's (as recommended in the BC-FIPS documentation). I applied all the recommended changes except the one that initializes the security provider, since I cannot configure the JDK to load BC classes from the lib/ext folder since they are no longer supported in JDK-11. A suggested alternative is to place the location of that class in the classpath during application startup. However, I also discovered that this doesn't work due to a conflict with how uber-jar class loading works (in fact, that class is technically in the classpath of uber-jar). Additionally, we are replacing the default keystore format from JKS to BCFKS to comply with BC-FIPS KeyStore requirements. Technically JKS is fine for certificate stores, but honestly I didn't even want to enable JKS support in case I ran into problems elsewhere.

If your database is in the cloud (such as AWS or Azure), you may need to add a certificate to cacerts to enable database connections using JSSE (BC-FIPS or native Java JSSE code). Do this for the cacerts file of your deployed JDK.

keytoolkey store cacertsBig pass secretwithout any prompttrust agencyImport certificate -Nickname awscert -file certificate.der

Next, to convert cacert to BCFIPS format, you need to do the following:

keytoolimport key storesrckeystore cacertssrcstoretype JKS-srcstorepass change \

handkerchief shop jssecacertsdeststorepass changestorage type BCFKSsupplier name BCFIPS\

-Provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider –provider path lib/B.C.pip-

See also  Covering the Land with CCBHC

This will perform the conversion and create a new file “jssecacerts” in BCFKS format. The JDK looks for jssecacert before cacert, so now both formats remain in case you need them.

A simpler way to perform this conversion is to use KeyStore Explorer. This is a tool I frequently use to inspect/modify keys and trust repository contents. The tool already has BCFKS support built in, even though it is not compatible with BCFIPS (direct BC also supports the BCFKS format, but it is not a certified component).

Finally, you will need to change how you configure SSL/TLS for your server and/or client components. Our system configures it programmatically using beans for KeyStore, TrustStore, etc., but other servers might just use properties or configuration values ​​(e.g. server.xml for Tomcat).

If you have a default keystore type, you should change the keystore type to BCFKS, and if the provider type is specified, use BCFIPS (as with the keytool command above).

If you want to get the KeyManagerFactory, TrustManagerFactory, or SSLContext programmatically, here's how to get it:

KeyManagerFactory keyMgrFact = KeyManagerFactory.getInstance(“PKIX”, BCJSSE);
TrustManagerFactory trustMgrFact = TrustManagerFactory.getInstance(“PKIX”, BCJSSE);
SSLContext sslContext = SSLContext.getInstance(“TLS”, BCJSSE);

If you have a default key store type, you must change the key store type to BCFKS, and if you need to specify a key store provider, specify BCFIPS as the provider.

This ensures that all encryption used to protect keys and trust material is FIPS-compliant. Unfortunately, the encryption used in the JKS or PKCS12 formats are themselves compliant.

As these efforts continue, I recently completed another set of code changes that allow adding new keys and trust stores to the shared file system. All servers will then automatically be rebuilt to the latest and greatest level. This greatly simplifies updating certificates for annual renewals or other reasons without downtime. More on this later.

See also  PMS Linked to More Severe Hot Flashes and Night Sweats in Menopause

Leave a Reply

Your email address will not be published. Required fields are marked *