---
title: FIPS 140-3 compliance
description: To achieve FIPS 140-3 compliance, configure the Bouncy Castle FIPS libraries with IDM. This enables the use of the Bouncy Castle FIPS key store and security provider in FIPS-approved mode.
component: pingidm
version: 8.1
page_id: pingidm:security-guide:security-bouncy-castle-fips
canonical_url: https://docs.pingidentity.com/pingidm/8.1/security-guide/security-bouncy-castle-fips.html
keywords: ["Security", "Bouncy Castle FIPS", "Keystores", "Cryptographic Keys", "Secrets", "JSON", "Configuration", "JVM"]
section_ids:
  download-bouncy-castle-libraries: Download the Bouncy Castle libraries
  enable-bouncy-castle-in-jvm: Enable the Bouncy Castle FIPS provider in the JVM
  add-bouncy-castle-existing-jvm: Add Bouncy Castle providers to the existing JVM
  add-bouncy-castle-idm-config: Add Bouncy Castle providers to IDM conf/java.security
  create-bouncy-castle-crypto-keys: Create the IDM Bouncy Castle key store and cryptographic keys
  bouncy-castle-jvm-to-idm: Provide the JVM to IDM
  configure-bouncy-castle-keystore: Configure the Bouncy Castle key store in secrets.json
  disable_bouncy_castle_fips_approved_mode: Disable Bouncy Castle FIPS-approved mode
  allow-rsa-key-multi-use: Allow RSA key multi-use
---

# FIPS 140-3 compliance

To achieve [FIPS 140-3](https://csrc.nist.gov/pubs/fips/140-3/final) compliance, configure the [Bouncy Castle FIPS libraries](https://www.bouncycastle.org/fips-java/) with IDM. This enables the use of the Bouncy Castle FIPS key store and security provider in FIPS-approved mode.

Bouncy Castle FIPS is crucial when dealing with government data, where you must meet the FIPS 140-3 security requirement for regulatory compliance.

|   |                                                                                                                                                        |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|   | Bouncy Castle FIPS is less performant than other key stores. The destroyable keys cannot be cached and must be read from the key store with every use. |

To configure IDM to use Bouncy Castle FIPS:

1. [Download the Bouncy Castle libraries](#download-bouncy-castle-libraries).

2. [Enable the Bouncy Castle FIPS provider in the JVM](#enable-bouncy-castle-in-jvm).

3. [Create the IDM cryptographic keys](#create-bouncy-castle-crypto-keys).

4. [Provide the JVM to IDM](#bouncy-castle-jvm-to-idm).

5. [Configure the Bouncy Castle key store in `secrets.json`](#configure-bouncy-castle-keystore).

## Download the Bouncy Castle libraries

|   |                                                                                          |
| - | ---------------------------------------------------------------------------------------- |
|   | The [IDM CLI](../setup-guide/chap-cli.html) does not work when using Bouncy Castle FIPS. |

To use Bouncy Castle FIPS with IDM, download the libraries:

1. Download the following libraries from [Bouncy Castle](https://www.bouncycastle.org/fips-java/) to the server/machine where IDM is deployed:

   | File                                     | Description                                                             |
   | ---------------------------------------- | ----------------------------------------------------------------------- |
   | `bc-fips-latestVersionNumber.jar`(1)     | Contains the Bouncy Castle FIPS security provider implementation.       |
   | `bcpkix-fips-latestVersionNumber.jar`(2) | Provides FIPS support for cert generation.                              |
   | `bctls-fips-latestVersionNumber.jar`(3)  | Provides TLS support using FIPS compliance.                             |
   | `bcmail-fips-latestVersionNumber.jar`(4) | The Bouncy Castle Java APIs for doing S/MIME with JavaMail.             |
   | `bcutil-fips-latestVersionNumber.jar`(5) | The Bouncy Castle Java APIs for ASN.1 extension and other utility APIs. |

   (1) The tested version is `bc-fips-2.1.2.jar`.

   (2) The tested version is `bcpkix-fips-2.1.9.jar`.

   (3) The tested version is `bctls-fips-2.1.20.jar`.

   (4) The tested version is `bcmail-fips-2.1.6.jar`.

   (5) The tested version is `bcutil-fips-2.1.4.jar`.

2. Copy the downloaded files to `/path/to/openidm/bundle`.

3. Restart IDM.

## Enable the Bouncy Castle FIPS provider in the JVM

To enable the Bouncy Castle FIPS provider in your JVM, do one of the following:

* [Add Bouncy Castle providers to the existing JVM](#add-bouncy-castle-existing-jvm)

* [Add Bouncy Castle providers to IDM `conf/java.security`](#add-bouncy-castle-idm-config)

### Add Bouncy Castle providers to the existing JVM

If the existing JVM supports Bouncy Castle, then you can add the security providers to the JVM.

Add the Bouncy Castle security providers to `$JAVA_HOME/conf/security/java.security` as the first and second security providers:

```bash
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:HYBRID;ENABLE{All};
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
```

|   |                                                                                                                                  |
| - | -------------------------------------------------------------------------------------------------------------------------------- |
|   | The Bouncy Castle security providers should be 1 and 2. You should add any other security providers necessary for your use case. |

### Add Bouncy Castle providers to IDM `conf/java.security`

If the existing JVM supports Bouncy Castle, then you can add the security providers to the `/path/to/openidm/conf/java.security`.

Add the Bouncy Castle security providers to `/path/to/openidm/conf/java.security`:

```bash
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:HYBRID;ENABLE{All};
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
```

|   |                                                                                                                                                                                    |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | This file overrides the `$JAVA_HOME/conf/security/java.security` file. You should also add any additional security providers from that file which are necessary for your use case. |

## Create the IDM Bouncy Castle key store and cryptographic keys

|   |                                                                                                                                       |
| - | ------------------------------------------------------------------------------------------------------------------------------------- |
|   | Before you create the cryptographic keys, you must [Enable the Bouncy Castle FIPS provider in the JVM](#enable-bouncy-castle-in-jvm). |

To create the necessary IDM cryptographic keys:

1. Create the Bouncy Castle key store. This can be done in conjunction with creating the first cryptographic key:

   ```bash
   keytool \
   -genseckey \
   -alias openidm-sym-default \
   -keyalg aes \
   -keysize 256 \
   -keystore /location/to/keystore.bcfks \
   -storepass changeit -storetype BCFKS \
   -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
   -providerpath /path/to/bc-fips-2.1.2.jar
   ```

   This creates the `openidm-sym-default` key in a key store called /location/to/keystore.bcfks while also creating that keystore if it does not exist.

   |   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | You must use the JVM specific keytool that the Bouncy Castle security provider uses.For example, if you enable the security providers in the [system default JVM](#add-bouncy-castle-existing-jvm), you must use the system default keytool command.The keytool command is in the `bin` directory of the JVM Java home.Failure to use the `keytool` command you configure for Bouncy Castle results in the following error:```bash
   keytool error: java.lang.Exception: Provider "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider" not found
   ``` |

2. Create the remaining keys:

   Create the `openidm-selfservice-key`

   ```bash
   keytool \
   -genseckey \
   -alias openidm-selfservice-key \
   -keyalg aes \
   -keysize 256 \
   -keystore /location/to/keystore.bcfks \
   -storepass changeit \
   -storetype BCFKS \
   -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
   -providerpath /path/to/bc-fips-2.1.2.jar
   ```

   Create the `openidm-jwtsessionhmac-key`

   ```bash
   keytool \
   -genseckey \
   -alias openidm-jwtsessionhmac-key \
   -keyalg aes \
   -keysize 256 \
   -keystore /location/to/keystore.bcfks \
   -storepass changeit \
   -storetype BCFKS \
   -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
   -providerpath /path/to/bc-fips-2.1.2.jar
   ```

   Create the `openidm-localhost` key

   ```bash
   keytool \
   -genkey \
   -alias openidm-localhost \
   -keyalg RSA \
   -keysize 2048 \
   -keystore /location/to/keystore.bcfks \
   -storepass changeit \
   -storetype BCFKS \
   -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
   -providerpath /path/to/bc-fips-2.1.2.jar
   ```

   Create the `selfservice` key

   ```bash
   keytool \
   -genkey \
   -alias selfservice \
   -keyalg RSA \
   -keysize 2048 \
   -keystore /location/to/keystore.bcfks \
   -storepass changeit \
   -storetype BCFKS \
   -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
   -providerpath /path/to/bc-fips-2.1.2.jar
   ```

## Provide the JVM to IDM

IDM uses only the default system Java and `JAVA_HOME` defined in the `/path/to/openidm/startup.sh` file:

Default `startup.sh` file

```bash
if which java &>/dev/null; then
    JAVA=java
elif [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ];  then
    JAVA="$JAVA_HOME/bin/java"
else
    echo JAVA_HOME not available, Java is needed to run IDM
    echo Please install Java and set JAVA_HOME accordingly
    exit 1
fi
```

Learn more about limitations in [Bouncy Castle FIPS with custom JVM](../release-notes/limitations.html#limitations-bouncy-castle-fips).

## Configure the Bouncy Castle key store in `secrets.json`

After you add the [Bouncy Castle security providers](#enable-bouncy-castle-in-jvm) and [create the key store and keys](#create-bouncy-castle-crypto-keys), you must replace the default IDM key store with the new Bouncy Castle key store in `/path/to/openidm/conf/secrets.json`:

```bash
        {
            "name" : "mainKeyStore",
            "class" : "org.forgerock.openidm.secrets.config.KeyStoreSecretStore",
            "config" : {
                "file" : "&{idm.install.dir}/security/keystore.bcfks",
                "storetype" : "BCFKS",
                "providerName" : "BCFIPS",
                "storePassword" : "changeit",
                "mappings" : [
                    {
                        "secretId" : "idm.default",
                        "types" : [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.alias|openidm-sym-default}"
                        ]
                    },
                    {
                        "secretId" : "idm.config.encryption",
                        "types" : [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.alias|openidm-sym-default}"
                        ]
                    },
                    {
                        "secretId": "idm.password.encryption",
                        "types": [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.alias|openidm-sym-default}"
                        ]
                    },
                    {
                        "secretId" : "idm.jwt.session.module.encryption",
                        "types" : [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "&{openidm.https.keystore.cert.alias|openidm-localhost}"
                        ]
                    },
                    {
                        "secretId" : "idm.jwt.session.module.signing",
                        "types" : [
                            "SIGN",
                            "VERIFY"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.jwtsession.hmackey.alias|openidm-jwtsessionhmac-key}"
                        ]
                    },
                    {
                        "secretId" : "idm.selfservice.encryption",
                        "types" : [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "selfservice"
                        ]
                    },
                    {
                        "secretId" : "idm.selfservice.signing",
                        "types" : [
                            "SIGN",
                            "VERIFY"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.selfservice.sharedkey.alias|openidm-selfservice-key}"
                        ]
                    },
                    {
                        "secretId" : "idm.assignment.attribute.encryption",
                        "types" : [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.alias|openidm-sym-default}"
                        ]
                    }
                ]
            }
        },
```

IDM is now configured to start using the Bouncy Castle key store.

## Disable Bouncy Castle FIPS-approved mode

By default, IDM turns on Bouncy Castle in FIPS-approved mode. This makes Bouncy Castle FIPS 140-3 compliant.

IDM sets the configuration in `/path/to/openidm/startup.sh` and `/path/to/openidm/bin/docker-entrypoint.sh` using the following property:

```bash
org.bouncycastle.fips.approved_only=true
```

To disable FIPS-approved mode, change `org.bouncycastle.fips.approved_only` to `false`.

|   |                                                                                                                                                                                                                                                                                                                                        |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | In `startup.sh` and `docker-entrypoint.sh`, the `org.bouncycastle.jca.enable_jks` property enables the JKS-format Java key store for FIPS. To maintain compliance, this key store can only be used for reading JKS key stores containing certificates.By default, this property is `false`. To enable the key store, set it to `true`. |

|   |                                                                                                                                               |
| - | --------------------------------------------------------------------------------------------------------------------------------------------- |
|   | These settings must take place early in the IDM start process per the [Bouncy Castle documentation](https://www.bouncycastle.org/fips-java/). |

## Allow RSA key multi-use

By default, the Bouncy Castle FIPS module prevents an RSA modulus from being used for both encryption and signing operations. This is a security measure to avoid potential vulnerabilities.

However, specific scenarios might require an RSA key to be used for both purposes. To allow this, set:

```bash
org.bouncycastle.rsa.allow_multi_use=true
```

|   |                                                                                                                                                                                                                                                                                          |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Enabling this property relaxes a security control. Understand the implications before setting `org.bouncycastle.rsa.allow_multi_use=true`. Consult relevant security best practices and the [Bouncy Castle documentation](https://www.bouncycastle.org/fips-java/) for more information. |
