diff --git a/docs/documentation/upgrading/topics/changes/changes-26_0_0.adoc b/docs/documentation/upgrading/topics/changes/changes-26_0_0.adoc
index c4bd775d1c..62b010fe92 100644
--- a/docs/documentation/upgrading/topics/changes/changes-26_0_0.adoc
+++ b/docs/documentation/upgrading/topics/changes/changes-26_0_0.adoc
@@ -300,6 +300,14 @@ The new event types are supported by the Email Event Listener.
The following event types are now deprecated and will be removed in a future version: `UPDATE_PASSWORD`, `UPDATE_PASSWORD_ERROR`, `UPDATE_TOTP`, `UPDATE_TOTP_ERROR`, `REMOVE_TOTP`, `REMOVE_TOTP_ERROR`
+= BouncyCastle FIPS updated
+
+Our FIPS 140-2 integration is now tested and supported with version 2 of BouncyCastle FIPS libraries. This version is certified with Java 21. If you use FIPS 140-2 integration, it is recommended to
+upgrade BouncyCastle FIPS library to the versions mentioned in the latest documentation.
+
+The BouncyCastle FIPS version 2 is certified with FIPS 140-3. So {project_name} can be FIPS 140-3 compliant as long as it is used on the FIPS 140-3 compliant system.
+This might be the RHEL 9 based system, which itself is compliant with the FIPS 140-3. But note that RHEL 8 based system is only certified for the FIPS 140-2.
+
= `setOrCreateChild()` method removed from JavaScript Admin Client
The `groups.setOrCreateChild()` method has been removed from that JavaScript-based Admin Client. If you are still using this method then use the `createChildGroup()` or `updateChildGroup()` methods instead.
diff --git a/docs/guides/server/fips.adoc b/docs/guides/server/fips.adoc
index 4ce0aea24f..2b5cb10c41 100644
--- a/docs/guides/server/fips.adoc
+++ b/docs/guides/server/fips.adoc
@@ -37,12 +37,13 @@ When {project_name} executes in fips mode, it will use the BCFIPS bits instead o
=== BouncyCastle FIPS bits
-BouncyCastle FIPS can be downloaded from the https://www.bouncycastle.org/fips-java/[BouncyCastle official page]. Then you can add them to the directory
+BouncyCastle FIPS can be downloaded from the https://www.bouncycastle.org/download/bouncy-castle-java-fips/[BouncyCastle official page]. Then you can add them to the directory
`KEYCLOAK_HOME/providers` of your distribution. Make sure to use proper versions compatible with BouncyCastle {project_name} dependencies. The supported BCFIPS bits needed are:
* bc-fips version ${properties["bouncycastle.bcfips.version"]}.
* bctls-fips version ${properties["bouncycastle.bctls-fips.version"]}.
* bcpkix-fips version ${properties["bouncycastle.pkixfips.version"]}.
+* bcutil-fips version ${properties["bouncycastle.bcutilfips.version"]}.
== Generating keystore
@@ -154,17 +155,18 @@ always fulfils this requirement.
== Other restrictions
To have SAML working, make sure that a `XMLDSig` security provider is available in your security providers.
-To have Kerberos working, make sure that a `SunJGSS` security provider is available. In FIPS enabled RHEL 9 in OpenJDK 17.0.6, these
-security providers are not present in the `java.security`, which means that they effectively cannot work.
+To have Kerberos working, make sure that a `SunJGSS` security provider is available. In FIPS enabled RHEL 9 in OpenJDK 21, the `XMLDSig` security provider may be already enabled
+in the `java.security` by default and the same applies with latest OpenJDK 17. But with older OpenJDK 17, it may not be enabled by default, which means that SAML effectively cannot work.
-To have SAML working, you can manually add the provider into `JAVA_HOME/conf/security/java.security` into the list fips providers. For example, add the line such as the following:
+To have SAML working, you can manually add the provider into `JAVA_HOME/conf/security/java.security` into the list fips providers. For example, add the line such as the following in case
+that it is not already available in your FIPS security providers:
[source]
----
fips.provider.7=XMLDSig
----
-Adding this security provider should work well. In fact, it is FIPS compliant and likely will be added by default in the future OpenJDK 17 micro version.
+Adding this security provider should work well. In fact, it is FIPS compliant and is already added by default in the OpenJDK 21.
Details are in the https://bugzilla.redhat.com/show_bug.cgi?id=1940064[bugzilla].
NOTE: It is recommended to look at `JAVA_HOME/conf/security/java.security` and check all configured providers here and make sure that the number matches. In other words, `fips.provider.7`
@@ -195,6 +197,7 @@ it detects that corresponding BCFIPS jars are present (see above for the version
----
cp $KEYCLOAK_HOME/providers/bc-fips-*.jar $KEYCLOAK_HOME/bin/client/lib/
cp $KEYCLOAK_HOME/providers/bctls-fips-*.jar $KEYCLOAK_HOME/bin/client/lib/
+cp $KEYCLOAK_HOME/providers/bcutil-fips-*.jar $KEYCLOAK_HOME/bin/client/lib/
----
NOTE: When trying to use BCFKS truststore/keystore with CLI, you may see issues due this truststore is not the default java keystore type. It can be good to specify it as default in java
@@ -223,7 +226,7 @@ For example in the current directory, you can create sub-directory `files` and a
* BC FIPS jar files as described above
* Custom keystore file - named for example `keycloak-fips.keystore.bcfks`
-* Security file `kc.java.security` with added provider for SAML
+* Security file `kc.java.security` with added provider for SAML (Not needed with OpenJDK 21 or newer OpenJDK 17)
Then create `Containerfile` in the current directory similar to this:
diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/ClassLoaderUtil.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/ClassLoaderUtil.java
index 3ce4afaa08..6ce16c28aa 100644
--- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/ClassLoaderUtil.java
+++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/ClassLoaderUtil.java
@@ -38,7 +38,7 @@ public class ClassLoaderUtil {
// Detect if BC FIPS jars are present in the "client/lib" directory
boolean bcFipsJarPresent = Stream.of(jarsInDir).anyMatch(file -> file.getName().startsWith("bc-fips"));
- String[] validJarPrefixes = bcFipsJarPresent ? new String[] {"keycloak-crypto-fips1402", "bc-fips", "bctls-fips"} : new String[] {"keycloak-crypto-default", "bcprov-jdk18on"};
+ String[] validJarPrefixes = bcFipsJarPresent ? new String[] {"keycloak-crypto-fips1402", "bc-fips", "bctls-fips","bcutil-fips"} : new String[] {"keycloak-crypto-default", "bcprov-jdk18on"};
URL[] usedJars = Stream.of(jarsInDir)
.filter(file -> {
for (String prefix : validJarPrefixes) {
diff --git a/pom.xml b/pom.xml
index 19666b124a..ea63d2d03c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,10 +86,10 @@