Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.minimus.io/llms.txt

Use this file to discover all available pages before exploring further.

What FIPS means for Java

FIPS (Federal Information Processing Standards) 140-3 is a federal cryptography compliance framework. FIPS validated cryptography is required by FedRAMP and is mandatory for non-military federal government agencies, contractors, and vendors. Validation is regulated by the NIST Cryptographic Module Validation Program (CMVP), which certifies cryptographic modules that meet FIPS 140-3 security standards. Standard OpenJDK ships with built-in cryptographic providers (SunJCE, SunJSSE, SunRsaSign, SunEC) that have not been through the CMVP validation process. To be FIPS-compliant, every cryptographic operation (encryption, hashing, key generation, TLS) must go through a CMVP-certified provider.

FIPS 140-3 certificate

Minimus Java FIPS images use the Minimus Cryptographic Module for Java module, validated under CMVP certificate #5142. This certificate covers the CCJ Provider and defines the approved algorithms, operational environments, and hardware requirements under which the module is validated.

Available Java FIPS images

Minimus provides the following Java FIPS validated images:
ImageBaseDescriptionUse
reg.mini.dev/openjdk-fipsEclipse TemurinOpenJDK Development Kit (JDK)Build and compile stage
reg.mini.dev/openjre-fipsEclipse TemurinOpenJDK Runtime Environment (JRE)Production runtime
reg.mini.dev/amazon-corretto-jdk-fipsAmazon CorrettoAmazon Corretto JDKBuild and compile stage
reg.mini.dev/amazon-corretto-jre-fipsAmazon CorrettoAmazon Corretto JREProduction runtime

Supported Java versions

Supported Java versions: 25, 21, 17, 11. Java 24 has reached end-of-life.

Cryptographic providers

Minimus Java FIPS images are configured with the following security providers, in priority order:
PositionProviderRole
1SafeLogic CryptoComply (CCJ)Primary FIPS 140-3 validated provider for all cryptographic operations
2Bouncy Castle JSSE (BCJSSE)FIPS-compliant TLS/SSL — delegates all crypto to CCJ
3SUNLoaded at lowest priority for CCJ JAR signature validation only
4+SunJGSS, SunSASL, XMLDSig, SunPCSC, JdkLDAP, JdkSASLInfrastructure providers delegate crypto operations to CCJ/BCJSSE
The following providers are explicitly removed from the image and are not available at runtime: SunRsaSign, SunEC, SunJCE, SunJSSE.

FIPS 140-3 libraries

The CryptoComply and SafeLogic Bouncy Castle jars are located at /usr/share/fips-libs/ inside the image:
JARPurpose
ccj-4.0.0-fips.jarSafeLogic CryptoComply FIPS 140-3 provider (CCJ)
sl-bcutil-2.0.3.jarSafeLogic Bouncy Castle utilities
sl-bctls-2.0.21.jarSafeLogic Bouncy Castle TLS/SSL (JSSE)
sl-bcpkix-2.0.8.jarSafeLogic Bouncy Castle PKIX/X.509
sl-bcmail-2.0.5.jarSafeLogic Bouncy Castle S/MIME
sl-bcpg-2.0.12.jarSafeLogic Bouncy Castle OpenPGP

What FIPS blocks at runtime

FIPS approved-only mode (com.safelogic.cryptocomply.fips.approved_only=true) enforces a hard algorithm blocklist. Your application will throw a NoSuchAlgorithmException or GeneralSecurityException at runtime, not at compile time if it calls any of the following:
BlockedFIPS-approved replacement
MD5 (for any security purpose)SHA-256 or SHA-3
SHA-1 signaturesSHA-256 or stronger
DES / 3DESAES-128 or AES-256
RC4AES-GCM
TLS 1.0 / TLS 1.1TLS 1.2 or TLS 1.3
RSA or DH keys under 2048 bitsRSA-2048 minimum, RSA-3072 preferred
PKCS#12 for private key storageBCFKS keystore format
Audit your codebase to search for string literals like “MD5”, “SHA1”, “DES”, “RC4”, “TLSv1”, and “PKCS12” in any getInstance() or KeyStore.getInstance() calls.

Security configuration

The images enforce FIPS 140-3 compliance through:
  • Approved-only mode: com.safelogic.cryptocomply.fips.approved_only=true
  • Non-FIPS providers disabled: SunRsaSign, SunEC, SunJCE, and SunJSSE are omitted
  • FIPS-approved algorithms only: Non-FIPS algorithms are blocked (e.g., MD5)
  • BCFKS keystore type: Required for private keys (Bouncy Castle FIPS KeyStore is a FIPS-compliant keystore format)
  • Trust store types: JKS, PKCS12, and BCFKS supported for truststores

Environment variables

Minimus Java FIPS images set the following environment variables by default:
  • JAVA_HOME: Points to the default JVM installation
  • CLASSPATH: Includes FIPS libraries from /usr/share/fips-libs/*
  • JAVA_FIPS_CLASSPATH: Explicit FIPS classpath reference
  • JDK_JAVA_OPTIONS: Includes the required exports and FIPS trust store configuration:
    --add-exports=java.base/sun.security.internal.spec=ALL-UNNAMED
    --add-exports=java.base/sun.security.provider=ALL-UNNAMED
    -Djavax.net.ssl.trustStoreType=FIPS
    

Verifying the Java FIPS 140-3 module

Each Java FIPS image includes automated tests that verify:
  1. Java version - Confirms that the correct Java version is installed
  2. FIPS provider availability - Verifies that SafeLogic CryptoComply and Bouncy Castle JSSE providers are loaded
  3. Provider priority - Ensures providers are in the correct order (CCJ at position 1, BCJSSE at position 2)
  4. FIPS-approved algorithms - Tests that FIPS-approved algorithms (AES, SHA-256, RSA) are available
  5. Non-FIPS algorithm blocking - Confirms non-FIPS algorithms (e.g., MD5) are correctly blocked

Basic verification

# Run a Java application with FIPS compliance
docker run --rm reg.mini.dev/openjdk-fips:21 java -version

# Compile and run Java code
docker run --rm -v $(pwd):/home/build reg.mini.dev/openjdk-fips:21 \
  javac MyApp.java && java MyApp

FIPS compliance test

You can verify FIPS compliance by creating a test program. For example, save the following code as the file TestFIPS.java:
TestFIPS.java
import java.security.Provider;
import java.security.Security;

public class TestFIPS {
    public static void main(String[] args) {
        System.out.println("=== FIPS Compliance Test ===");

        // Check that FIPS approved only mode is enabled
        String approvedOnly = Security.getProperty("com.safelogic.cryptocomply.fips.approved_only");
        boolean isApprovedOnly = approvedOnly != null && approvedOnly.equals("true");

        if (!isApprovedOnly) {
            System.err.println("[ERROR] SafeLogic CryptoComply FIPS Approved Only Mode is disabled!");
            System.exit(1);
        }

        // Check that providers are loaded
        Provider[] providers = Security.getProviders();
        boolean foundCryptoComply = false;
        boolean foundBCJSSE = false;
        int cryptoComplyPosition = -1;
        int bcjssePosition = -1;

        for (int i = 0; i < providers.length; i++) {
            Provider provider = providers[i];
            String name = provider.getName();
            if (name.contains("CCJ") || name.contains("CryptoComply")) {
                foundCryptoComply = true;
                cryptoComplyPosition = i + 1;
                System.out.println("[OK] SafeLogic CryptoComply provider found at position " + cryptoComplyPosition);
            }
            if (name.contains("BouncyCastleJsse") || name.contains("BCJSSE")) {
                foundBCJSSE = true;
                bcjssePosition = i + 1;
                System.out.println("[OK] Bouncy Castle JSSE provider found at position " + bcjssePosition);
            }
        }

        if (!foundCryptoComply) {
            System.err.println("[ERROR] SafeLogic CryptoComply provider NOT found!");
            System.exit(1);
        }
        if (!foundBCJSSE) {
            System.err.println("[ERROR] Bouncy Castle JSSE provider NOT found!");
            System.exit(1);
        }

        // Check provider positions
        if (cryptoComplyPosition != 1) {
            System.err.println("[WARNING] SafeLogic CryptoComply provider is at position " + cryptoComplyPosition + ", expected position 1");
        } else {
            System.out.println("[OK] SafeLogic CryptoComply provider is at correct position (1)");
        }

        if (bcjssePosition != 2) {
            System.err.println("[WARNING] Bouncy Castle JSSE provider is at position " + bcjssePosition + ", expected position 2");
        } else {
            System.out.println("[OK] Bouncy Castle JSSE provider is at correct position (2)");
        }

        // Test FIPS-approved algorithms
        try {
            // Test AES (FIPS-approved)
            javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding", "CCJ");
            System.out.println("[OK] AES algorithm available");

            // Test SHA-256 (FIPS-approved)
            java.security.MessageDigest.getInstance("SHA-256", "CCJ");
            System.out.println("[OK] SHA-256 algorithm available");

            // Test RSA (FIPS-approved)
            java.security.KeyPairGenerator.getInstance("RSA", "CCJ");
            System.out.println("[OK] RSA algorithm available");

            // Test that MD5 is correctly blocked (non-FIPS)
            try {
                java.security.MessageDigest md5 = java.security.MessageDigest.getInstance("MD5", "CCJ");
                System.err.println("[ERROR] MD5 is available (provider: " + md5.getProvider().getName() + ")");
                System.err.println("[ERROR] FIPS mode is not fully enforced - MD5 should be blocked!");
                System.exit(1);
            } catch (Exception e) {
                System.out.println("[OK] MD5 correctly blocked by FIPS compliance: " + e.getMessage());
            }

            System.out.println("=== FIPS Compliance Test PASSED ===");

        } catch (Exception e) {
            System.err.println("[ERROR] FIPS algorithm test failed: " + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
    }
}
Compile and run the FIPS test:
docker run --rm -v $(pwd):/home/build minimus/openjdk-fips:21 sh -c \
  "javac TestFIPS.java && java TestFIPS"
Expected output:
=== FIPS Compliance Test ===
[OK] SafeLogic CryptoComply provider found at position 1
[OK] Bouncy Castle JSSE provider found at position 2
[OK] SafeLogic CryptoComply provider is at correct position (1)
[OK] Bouncy Castle JSSE provider is at correct position (2)
[OK] AES algorithm available
[OK] SHA-256 algorithm available
[OK] RSA algorithm available
[OK] MD5 correctly blocked by FIPS compliance: ...
=== FIPS Compliance Test PASSED ===

Notes

  • FIPS compliance is enforced at runtime via Java security configurations
  • Applications must use FIPS-approved algorithms and keystore formats (BCFKS)
  • The Sun provider is included only for JAR signature validation and does not perform cryptographic operations
  • All cryptographic operations are routed through FIPS-validated providers (CCJ and BCJSSE)
  • The Java FIPS module requires specialized hardware. Learn more
Last modified on April 20, 2026