# Nexus Repository FIPS 140-3 Compliance

This guide provides instructions for Nexus Repository deployments to enable FIPS compliance in their existing or new environments.

## Federal Information Processing Standards (FIPS) Compliance

**FIPS 140-3**, or Federal Information Processing Standards, are a set of cybersecurity standards developed by the U.S. government to protect sensitive, unclassified data. FIPS compliance means that a product adheres to these specific standards, especially those related to cryptographic modules, which are essential for data encryption and security. This compliance is often a mandatory requirement for federal agencies and their contractors, and it is also widely adopted by private sector organizations to demonstrate a high level of security.

### Nexus Repository Truststore

Nexus Repository is configured as a proxy for public repositories, such as Maven Central or a private corporate repository. Nexus Repository is a client when connecting to these remote repositories over HTTPS. To validate the remote server's identity, Nexus Repository needs a truststore. By default, Nexus Repository uses the Java Virtual Machine's default truststore.

The default Java truststore, typically contains the public key certificates of Certificate Authorities (CAs) or a self-signed certificate from a trusted private corporate server. When a client receives a certificate from a server, it checks if that certificate was issued by a CA, or if the server's certificate itself is directly trusted by explicitly adding the self-signed certificate to the Nexus Repository truststore.

Since **Java (JDK) 9**, `PKCS12` (Public-Key Cryptography Standards #12) is the default keystore type in Java, replacing the older and less secure `JKS` (Java KeyStore) format. Both types use the same weak `changeit` password. This default configuration is not FIPS compliant.

To enable FIPS compliance, the truststores used by Nexus Repository must be updated to use the `BCFKS` keystore format while updating the passwords across the platform to use strong secure passwords. These changes need to be made for the default Java Truststore used by Nexus Repository for outgoing traffic as well as the internal web server (Jetty) used for SSL configuration.

- **OpenSSL library**: 3.5.2
- **FIPS provider module**: OpenSSL 3.1.2 FIPS
- **CMVP Certificate**: # [4985](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4985) (FIPS 140-3; valid until March 10, 2030)

**Note**  
Per OpenSSL guidance, the 3.1.2 FIPS provider is compatible across the OpenSSL 3.x series, making the 3.5.2 + 3.1.2 provider pairing an approved configuration when FIPS mode is correctly enabled.

### Bouncy Castle FIPS Keystore

Bouncy Castle FIPS Keystore or `BCFKS` is a keystore format developed by the Bouncy Castle library, specifically designed to be compliant with FIPS. BCFKS is built to use FIPS-compliant algorithms, such as `PBKDF2` for key derivation, `SHA-512` for hashing, and `AES CCM` for encryption. BCFKS is often used in environments that require FIPS-compliant cryptography, such as government or regulated industries. To use a BCFKS keystore, you typically need to use the Bouncy Castle FIPS provider.

- **Module**: `Bouncy Castle FIPS 2.1.0`
- **CMVP Certificate**: # [4943](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4943)

### Secure Passwords

The FIPS standard doesn't directly specify password policies for end-users, rather it dictates the security requirements for the cryptographic module that handles the authentication data. For a system to be FIPS-compliant, it must use FIPS-validated cryptographic algorithms when hashing passwords and generating cryptographic keys. **Passwords used to protect keys in a keystore and the database administrator must have an effective strength of at least 112 bits, which corresponds to a sufficiently long and random password.**

While FIPS focuses on the cryptographic implementation, `NIST SP 800-63-3` provides the practical, user-facing password policy that a FIPS-compliant system would likely adopt.

See [NIST - Digital Identity Guidelines](https://pages.nist.gov/800-63-3/)

## Prerequisites

- A valid FIPS-compatible license from Sonatype. The Nexus Repository Pro license is supported.
- A FIPS-compliant operating system (e.g., RHEL, Fedora, etc.).
- Ensure that the database administrator account used for the PostgreSQL connection is secured with a secure password.

## Overview

1. #### Upgrade to Nexus Repository 3.83 or Higher

FIPS compliance requires Nexus Repository 3.83 as the minimum required version.

See [Upgrade Nexus Repository](https://help.sonatype.com/en/upgrade-nexus-repository.html "Upgrade Nexus Repository")  
2. #### Secure Administrator Passwords

All administrator accounts must use passwords with a minimum strength of 112 bits of information entropy to comply with FIPS requirements.

See [Reset the Admin Password](https://help.sonatype.com/en/reset-the-admin-password.html "Reset the Admin Password")  
The database administrator account password is configured when setting up your postgres server and used to connect Nexus Repository to the server.

See [Install Nexus Repository with PostgreSQL](https://help.sonatype.com/en/install-nexus-repository-with-a-postgresql-database.html "Install Nexus Repository with a PostgreSQL Database")  
3. #### License Installation

Include the license file in an accessible path and set the corresponding property in `nexus.properties`. When launching Nexus Repository for the first time in a FIPS environment, the user interface is not accessible without first installing the license file.

See [License Management](https://help.sonatype.com/en/license-management.html "License Management")  
4. #### Password Manual Re-Hashing

Nexus Repository uses `SHA-512` for local user password encryption which is FIPS compliant. However, the FIPS guidelines recommend using `PBKDF2WithHmacSHA256` when deploying your environment. Updating the password encryption method requires that local users have their passwords rehashed in the database. Password are rehashed using the new algorithm when users next login to the UI.

See the [Local User Password Algorithm](https://help.sonatype.com/en/configuring-the-runtime-environment.html#local-user-password-algorithm "Local User Password Algorithm") section in Configuring the Runtime Environment

This process only applies to local Nexus Repository users. It does not apply to users authenticated via SAML or LDAP.

5. #### Secret Encryption

In Nexus Repository, secrets are encrypted using the `PBKDF2WithHmacSHA1` algorithm. The default key-password used for encryption is not FIPS compliant and flagged as insecure by the system health checks.

Use the following guide to re-encrypt Nexus Repository secrets.

See [Re-encryption in Nexus Repository](https://help.sonatype.com/en/re-encryption-in-nexus-repository.html "Re-encryption in Nexus Repository")  
6. #### Jetty SSL Configuration

The default `JKS/PKCS12` keystores used by Jetty configuration is not FIPS compatible nor is the default password secure. You must generate a new keystore of type `BCFKS`.

Use the following instructions to add a new `jetty-https-fips.xml` file to make the keystore type and file name default to `keystore.bcfks` with a strong password.

See the [Jetty SSL Configuration](https://help.sonatype.com/en/nexus-repository-fips-140-3-compliance.html#jetty-ssl-configuration "Jetty SSL Configuration") section below

7. #### Java Configuration

The default `JKS/PKCS12` keystores used by Java configuration is not FIPS compatible nor is the default password secure. You must generate a new keystore of type `BCFKS` for your Java truststore while updating the password to be secure. Additional configuration to Java is necessary to ensure your environment is FIPS compliant.

See the [Java Configuration for FIPS Compliance](https://help.sonatype.com/en/nexus-repository-fips-140-3-compliance.html#java-configuration-for-fips-compliance "Java Configuration for FIPS Compliance") section below

8. #### Enable FIPS

To enable FIPS mode, enable FIPS mode explicitly in your `nexus.properties` file:

```
nexus.security.fips.enabled=true
```

9. #### Resetting SAML Configuration (optional)

Your SAML configuration internally uses a keystore that might not be FIPS compliant. Resetting the configuration ensures it is created correctly.

You may reset SAML by deleting the existing SAML configuration using the API:

```
curl -u admin:admin123 --location --request DELETE 'http://localhost:8081/service/rest/v1/security/saml'
```

Review the [SAML configuration](https://help.sonatype.com/en/saml.html "SAML") documentation.

## Jetty SSL Configuration

Generate and place the `keynote.bcfks` in /etc/ssl directory using the following instructions.

```
BC_JAR="$HOME/.m2/repository/org/bouncycastle/bc-fips/2.1.0/bc-fips-2.1.0.jar"

keytool -genkeypair 
 -alias mykey 
 -keyalg RSA 
 -keysize 2048 
 -keystore keystore.bcfks 
 -storetype BCFKS 
 -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 
 -providerpath "$BC_JAR" 
 -storepass YourStrongPassword 
 -keypass YourStrongPassword 
 -validity 365 
 -dname "CN=*.example.com, OU=Sonatype, O=Sonatype, L=Unspecified, ST=Unspecified, C=US"

keytool -list -keystore keystore.bcfks 
 -storetype BCFKS 
 -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 
 -providerpath "$BC_JAR" 
 -storepass Password123456789#
```

1. Review the official guide on Configuring SSL.
   
   [Configuring SSL](https://help.sonatype.com/en/configuring-ssl.html "Configuring SSL")

2. Ensure that the following properties are set in the `nexus.properties` file:
   
   ```
application-port-ssl=8443

nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-https.xml,${jetty.etc}/jetty-https-fips.xml,${jetty.etc}/jetty-requestlog.xml

ssl.etc=${karaf.data}/etc/ssl

jetty.sslContext.keyStorePath=keystore.bcfks
```

3. Modify the `jetty-https.xml` file to include the truststore configuration:
   
   ```
<Set name="KeyStorePassword">YourStrongPassword</Set>
<Set name="KeyManagerPassword">YourStrongPassword</Set>
<Set name="TrustStorePassword">YourStrongPassword</Set>
```
4. Ensure your `openssl.cnf` includes the FIPS provider configuration:
   
   ```
config_diagnostics = 1
openssl_conf = openssl_init

.include /etc/ssl/fipsmodule.cnf

[openssl_init]
providers = provider_sect
alg_section = algorithm_sect

[provider_sect]
fips = fips_sect
base = base_sect

[base_sect]
activate = 1

[algorithm_sect]
default_properties = fips=yes
```

## Java Configuration for FIPS Compliance

1. Use the following example to place a new truststore using `BCFKS`. Set a strong password before running the script.
   
   ```
BC_JAR="$HOME/.m2/repository/org/bouncycastle/bc-fips/2.1.0/bc-fips-2.1.0.jar"
keytool -importkeystore 
     -srckeystore ${JAVA_HOME}/lib/security/cacerts 
     -srcstoretype JKS 
     -srcstorepass changeit 
     -destkeystore ${JAVA_HOME}/lib/security/truststore.bcfks 
     -deststoretype BCFKS 
     -deststorepass YourStrongPassword 
     -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider 
     -providerpath "$BC_JAR"
```

2. Set the following properties in your `nexus.vmoptions` file:
   
   ```
javax.net.ssl.trustStoreType=bcfks
javax.net.ssl.trustStore=pathToTruststore
javax.net.ssl.trustStorePassword=YourStrongPassword
```

3. Update your `java.security` file to include the following settings. These settings require your environment to run in FIPS compatible mode.
   
   ```
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
C:DEFRND[SHA256];ENABLE{ALL};org.bouncycastle.fips.approved_only=true
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=SUN
security.provider.4=XMLDSig
securerandom.strongAlgorithms=NativePRNGBlocking:SUN,NativePRNG:SUN
jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 2048
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 2048
crypto.policy=unlimited
keystore.type=bcfks
ssl.KeyManagerFactory.algorithm=PKIX
ssl.TrustManagerFactory.algorithm=PKIX
jdk.disabled.namedCurves=secp112r1, secp112r2, secp160k1, secp160r1, secp160r2, secp192k1
policy.url.1=file:${java.home}/conf/security/java.policy
securerandom.source=file:/dev/urandom
java.security.egd=file:/dev/urandom
```

4. Update your `java.policy` file should include the following permissions to allow required cryptographic operations:
   
   ```
grant {
permission java.lang.PropertyPermission "java.runtime.name", "read";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec";
     permission java.lang.RuntimePermission "getProtectionDomain";
     permission java.lang.RuntimePermission "accessDeclaredMembers";
     permission org.bouncycastle.crypto.CryptoServicesPermission "tlsAlgorithmsEnabled";
     permission org.bouncycastle.crypto.CryptoServicesPermission "exportKeys";
     permission org.bouncycastle.crypto.CryptoServicesPermission "defaultRandomConfig";
};
```
