PingIDM 7.5.0

FIPS 140-2 compliance

To achieve FIPS 140-2 compliance, configure the Bouncy Castle FIPS libraries with IDM. This enables the use of the Bouncy Castle FIPS keystore and security provider in FIPS-approved mode.

Bouncy Castle FIPS is useful when dealing with government data, where meeting the FIPS 140-2 security requirement is necessary for regulatory compliance.

Bouncy Castle FIPS is less performant than other keystores. The destroyable keys cannot be cached and must be read from the keystore with every use.

To configure IDM to use Bouncy Castle FIPS:

Download the Bouncy Castle libraries

The IDM CLI 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 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.

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

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

    (3) The tested version is bctls-fips-1.0.14.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

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:

security.provider.13=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:HYBRID;ENABLE{All};
security.provider.14=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
The security.provider.13 and security.provider.14 keys are JVM specific and must be the next 2 values in the security providers list.

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. This file provides additions to the $JAVA_HOME/conf/security/java.security file.

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

security.provider.13=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:HYBRID;ENABLE{All};
security.provider.14=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
The security.provider.13 and security.provider.14 keys are JVM specific and must be the next 2 values in the security providers list.

Build a distribution of the JVM that supports Bouncy Castle

If the existing JVM doesn’t support Bouncy Castle, you must create a new JVM distribution.

  1. Build a new distribution:

    $JAVA_HOME/bin/jlink \
    --no-header-files \
    --no-man-pages \
    --compress=2 \
    --module-path /Users/bjensen/Downloads \
    --add-modules java.base,java.compiler,java.datatransfer,java.desktop,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.se,java.security.jgss,java.security.sasl,java.smartcardio,java.sql,java.sql.rowset,java.transaction.xa,java.xml,java.xml.crypto,jdk.accessibility,jdk.aot,jdk.attach,jdk.charsets,jdk.compiler,jdk.crypto.cryptoki,jdk.crypto.ec,jdk.dynalink,jdk.editpad,jdk.hotspot.agent,jdk.httpserver,jdk.internal.ed,jdk.internal.jvmstat,jdk.internal.le,jdk.internal.opt,jdk.internal.vm.ci,jdk.internal.vm.compiler,jdk.internal.vm.compiler.management,jdk.jartool,jdk.javadoc,jdk.jcmd,jdk.jconsole,jdk.jdeps,jdk.jdi,jdk.jdwp.agent,jdk.jfr,jdk.jlink,jdk.jshell,jdk.jsobject,jdk.jstatd,jdk.localedata,jdk.management,jdk.management.agent,jdk.management.jfr,jdk.naming.dns,jdk.naming.ldap,jdk.naming.rmi,jdk.net,jdk.pack,jdk.rmic,jdk.scripting.nashorn,jdk.scripting.nashorn.shell,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.unsupported.desktop,jdk.xml.dom,jdk.zipfs,org.bouncycastle.fips.core,org.bouncycastle.fips.tls \
    --output /location/to/bouncy/castle/jvm --ignore-signing-information

    A customized JVM is created at the output location /location/to/bouncy/castle/jvm you specified.

  2. Add the Bouncy Castle security providers to /location/to/bouncy/castle/jvm/conf/security/java.security:

    security.provider.13=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:HYBRID;ENABLE{All};
    security.provider.14=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
    The security.provider.13 and security.provider.14 keys are JVM specific and must be the next 2 values in the security providers list.

Create the IDM Bouncy Castle keystore and cryptographic keys

Before you create the cryptographic keys, you must Enable the Bouncy Castle FIPS provider in the JVM.

To create the necessary IDM cryptographic keys:

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

    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

    This creates the openidm-sym-default key in a keystore 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, you must use the system default keytool command. If you create a custom JVM, you must use the keytool command for where that JVM is located.

    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:

    keytool error: java.lang.Exception: Provider "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider" not found
  2. Create the remaining keys:

    Create the openidm-selfservice-key
    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
    Create the openidm-jwtsessionhmac-key
    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
    Create the openidm-localhost key
    keytool \
    -genkey \
    -alias openidm-localhost \
    -keyalg RSA \
    -keysize 2048 \
    -keystore /location/to/keystore.bcfks \
    -storepass changeit \
    -storetype BCFKS \
    -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
    Create the selfservice key
    keytool \
    -genkey \
    -alias selfservice \
    -keyalg RSA \
    -keysize 2048 \
    -keystore /location/to/keystore.bcfks \
    -storepass changeit \
    -storetype BCFKS \
    -provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider

Provide the JVM to IDM

If you create a custom JVM location, you must to provide that JVM to IDM in the /path/to/openidm/startup.sh file.

By default, IDM uses the system Java and falls back to using the JAVA_HOME if the system Java is not defined:

Default startup.sh file
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

To configure IDM to use the JAVA_HOME you set, change the startup.sh file to the following:

Modified startup.sh file
if [ -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

Configure the Bouncy Castle keystore in secrets.json

After you add the Bouncy Castle security providers and create the keystore and keys, you must replace the default IDM keystore with the new Bouncy Castle keystore in /path/to/openidm/conf/secrets.json:

        {
            "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.assignment.attribute.encryption",
                        "types" : [
                            "ENCRYPT",
                            "DECRYPT"
                        ],
                        "aliases" : [
                            "&{openidm.config.crypto.alias|openidm-sym-default}"
                        ]
                    }
                ]
            }
        },

IDM is now configured to start using the Bouncy Castle keystore.

Disable Bouncy Castle FIPS-approved mode

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

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

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 there is also the property org.bouncycastle.jca.enable_jks=true. This property enables the Java keystore (JKS format) for FIPS. In order to maintain compliance, the keystore can only be used for reading a Java keystore that contains certificates. IDM sets this property to true by default.

These settings must take place early in the IDM start process per Bouncy Castle’s documentation.