diff --git a/crypto/default/src/main/java/org/keycloak/crypto/def/BCCertificateUtilsProvider.java b/crypto/default/src/main/java/org/keycloak/crypto/def/BCCertificateUtilsProvider.java
index 98ca18c9015..af05b681724 100755
--- a/crypto/default/src/main/java/org/keycloak/crypto/def/BCCertificateUtilsProvider.java
+++ b/crypto/default/src/main/java/org/keycloak/crypto/def/BCCertificateUtilsProvider.java
@@ -91,7 +91,7 @@ public class BCCertificateUtilsProvider implements CertificateUtilsProvider {
X500Name subjectDN = new X500Name("CN=" + subject);
// Serial Number
- SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom random = new SecureRandom();
BigInteger serialNumber = BigInteger.valueOf(Math.abs(random.nextInt()));
// Validity
diff --git a/crypto/default/src/main/java/org/keycloak/crypto/def/BCEcdhEsAlgorithmProvider.java b/crypto/default/src/main/java/org/keycloak/crypto/def/BCEcdhEsAlgorithmProvider.java
index d9a1db967c7..ac450f0aa6f 100644
--- a/crypto/default/src/main/java/org/keycloak/crypto/def/BCEcdhEsAlgorithmProvider.java
+++ b/crypto/default/src/main/java/org/keycloak/crypto/def/BCEcdhEsAlgorithmProvider.java
@@ -130,7 +130,7 @@ public class BCEcdhEsAlgorithmProvider implements JWEAlgorithmProvider {
private static KeyPair generateEcKeyPair(ECParameterSpec params) {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
- SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom randomGen = new SecureRandom();
keyGen.initialize(params, randomGen);
return keyGen.generateKeyPair();
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
diff --git a/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/BCFIPSCertificateUtilsProvider.java b/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/BCFIPSCertificateUtilsProvider.java
index 5a1bd610bea..51e12e096c5 100755
--- a/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/BCFIPSCertificateUtilsProvider.java
+++ b/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/BCFIPSCertificateUtilsProvider.java
@@ -92,7 +92,7 @@ public class BCFIPSCertificateUtilsProvider implements CertificateUtilsProvider{
X500Name subjectDN = new X500Name("CN=" + subject);
// Serial Number
- SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom random = new SecureRandom();
BigInteger serialNumber = BigInteger.valueOf(Math.abs(random.nextInt()));
// Validity
diff --git a/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/FIPS1402Provider.java b/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/FIPS1402Provider.java
index 5796e4f9d60..e590cef8872 100644
--- a/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/FIPS1402Provider.java
+++ b/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/FIPS1402Provider.java
@@ -1,6 +1,7 @@
package org.keycloak.crypto.fips;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
@@ -46,6 +47,7 @@ import javax.net.ssl.TrustManagerFactory;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.fips.FipsRSA;
import org.bouncycastle.crypto.fips.FipsSHS;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
@@ -91,17 +93,20 @@ public class FIPS1402Provider implements CryptoProvider {
providers.put(CryptoConstants.ECDH_ES_A192KW, new BCFIPSEcdhEsAlgorithmProvider());
providers.put(CryptoConstants.ECDH_ES_A256KW, new BCFIPSEcdhEsAlgorithmProvider());
- Security.insertProviderAt(new KeycloakFipsSecurityProvider(bcFipsProvider), 1);
if (existingBcFipsProvider == null) {
- checkSecureRandom(() -> Security.insertProviderAt(this.bcFipsProvider, 2));
+ checkSecureRandom(() -> Security.insertProviderAt(this.bcFipsProvider, 1));
Provider bcJsseProvider = new BouncyCastleJsseProvider("fips:BCFIPS");
- Security.insertProviderAt(bcJsseProvider, 3);
+ Security.insertProviderAt(bcJsseProvider, 2);
// force the key and trust manager factories if default values not present in BCJSSE
modifyKeyTrustManagerSecurityProperties(bcJsseProvider);
log.debugf("Inserted security providers: %s", Arrays.asList(this.bcFipsProvider.getName(),bcJsseProvider.getName()));
} else {
log.debugf("Security provider %s already loaded", existingBcFipsProvider.getName());
}
+
+ log.infof("FIPS1402Provider created: KC(%s%s, FIPS-JVM: %s)", bcFipsProvider,
+ CryptoServicesRegistrar.isInApprovedOnlyMode() ? " Approved Mode" : "",
+ isSystemFipsEnabled());
}
@@ -388,4 +393,23 @@ public class FIPS1402Provider implements CryptoProvider {
throw new IllegalStateException("Provider " + bcJsseProvider.getName()
+ " does not provide KeyManagerFactory or TrustManagerFactory algorithms for TLS");
}
+
+ public static String isSystemFipsEnabled() {
+ Method isSystemFipsEnabled = null;
+
+ try {
+ Class> securityConfigurator = FIPS1402Provider.class.getClassLoader().loadClass("java.security.SystemConfigurator");
+ isSystemFipsEnabled = securityConfigurator.getDeclaredMethod("isSystemFipsEnabled");
+ isSystemFipsEnabled.setAccessible(true);
+ boolean isEnabled = (boolean) isSystemFipsEnabled.invoke(null);
+ return isEnabled ? "enabled" : "disabled";
+ } catch (Throwable ignore) {
+ log.debug("Could not detect if FIPS is enabled from the host", ignore);
+ return "unknown";
+ } finally {
+ if (isSystemFipsEnabled != null) {
+ isSystemFipsEnabled.setAccessible(false);
+ }
+ }
+ }
}
diff --git a/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/KeycloakFipsSecurityProvider.java b/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/KeycloakFipsSecurityProvider.java
deleted file mode 100644
index f32b48a2ebb..00000000000
--- a/crypto/fips1402/src/main/java/org/keycloak/crypto/fips/KeycloakFipsSecurityProvider.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.keycloak.crypto.fips;
-
-import static org.bouncycastle.crypto.CryptoServicesRegistrar.isInApprovedOnlyMode;
-
-import java.lang.reflect.Method;
-import java.security.Provider;
-
-import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
-import org.jboss.logging.Logger;
-
-/**
- * Security provider to workaround usage of potentially unsecured algorithms by 3rd party dependencies.
- *
- * @author Marek Posolda
- */
-public class KeycloakFipsSecurityProvider extends Provider {
-
- protected static final Logger logger = Logger.getLogger(KeycloakFipsSecurityProvider.class);
-
- private final BouncyCastleFipsProvider bcFipsProvider;
-
- public KeycloakFipsSecurityProvider(BouncyCastleFipsProvider bcFipsProvider) {
- super("KC(" +
- bcFipsProvider.toString() +
- (isInApprovedOnlyMode() ? " Approved Mode" : "") +
- ", FIPS-JVM: " + isSystemFipsEnabled() +
- ")", 1, "Keycloak pseudo provider");
- this.bcFipsProvider = bcFipsProvider;
- logger.infof("KeycloakFipsSecurityProvider created: %s", this.toString());
- }
-
- @Override
- public synchronized final Service getService(String type, String algorithm) {
- // Using 'SecureRandom.getInstance("SHA1PRNG")' will delegate to BCFIPS DEFAULT provider instead of returning SecureRandom based on potentially unsecure SHA1PRNG
- if ("SHA1PRNG".equals(algorithm) && "SecureRandom".equals(type)) {
- logger.debug("Returning DEFAULT algorithm of BCFIPS provider instead of SHA1PRNG");
- return this.bcFipsProvider.getService("SecureRandom", "DEFAULT");
- } else {
- return null;
- }
- }
-
- public static String isSystemFipsEnabled() {
- Method isSystemFipsEnabled = null;
-
- try {
- Class> securityConfigurator = KeycloakFipsSecurityProvider.class.getClassLoader().loadClass("java.security.SystemConfigurator");
- isSystemFipsEnabled = securityConfigurator.getDeclaredMethod("isSystemFipsEnabled");
- isSystemFipsEnabled.setAccessible(true);
- boolean isEnabled = (boolean) isSystemFipsEnabled.invoke(null);
- return isEnabled ? "enabled" : "disabled";
- } catch (Throwable ignore) {
- logger.debug("Could not detect if FIPS is enabled from the host", ignore);
- return "unknown";
- } finally {
- if (isSystemFipsEnabled != null) {
- isSystemFipsEnabled.setAccessible(false);
- }
- }
- }
-}
diff --git a/crypto/fips1402/src/test/java/org/keycloak/crypto/fips/test/FIPS1402SecureRandomTest.java b/crypto/fips1402/src/test/java/org/keycloak/crypto/fips/test/FIPS1402SecureRandomTest.java
index 004c20c4ab0..509cc2e7650 100644
--- a/crypto/fips1402/src/test/java/org/keycloak/crypto/fips/test/FIPS1402SecureRandomTest.java
+++ b/crypto/fips1402/src/test/java/org/keycloak/crypto/fips/test/FIPS1402SecureRandomTest.java
@@ -38,16 +38,13 @@ public class FIPS1402SecureRandomTest {
SecureRandom sc1 = new SecureRandom();
logger.infof(dumpSecureRandom("new SecureRandom()", sc1));
+ Assert.assertEquals("DEFAULT", sc1.getAlgorithm());
+ Assert.assertEquals("BCFIPS", sc1.getProvider().getName());
SecureRandom sc2 = SecureRandom.getInstance("DEFAULT", "BCFIPS");
logger.infof(dumpSecureRandom("SecureRandom.getInstance(\"DEFAULT\", \"BCFIPS\")", sc2));
Assert.assertEquals("DEFAULT", sc2.getAlgorithm());
Assert.assertEquals("BCFIPS", sc2.getProvider().getName());
-
- SecureRandom sc3 = SecureRandom.getInstance("SHA1PRNG");
- logger.infof(dumpSecureRandom("SecureRandom.getInstance(\"SHA1PRNG\")", sc3));
- Assert.assertEquals("SHA1PRNG", sc3.getAlgorithm());
- Assert.assertEquals("BCFIPS", sc3.getProvider().getName());
}
diff --git a/docs/guides/server/fips.adoc b/docs/guides/server/fips.adoc
index b0b9cd77a5f..58d73931108 100644
--- a/docs/guides/server/fips.adoc
+++ b/docs/guides/server/fips.adoc
@@ -122,7 +122,7 @@ When starting the server, you can check that the startup log contains `KC` provi
[source]
----
-KeycloakFipsSecurityProvider created: KC(BCFIPS version 2.0102 Approved Mode, FIPS-JVM: enabled) version 1.0
+FIPS1402Provider created: KC(BCFIPS version 2.0102 Approved Mode, FIPS-JVM: enabled)
----
=== Cryptography restrictions in strict mode
diff --git a/pom.xml b/pom.xml
index 0a528f0bb07..b3579c32d98 100644
--- a/pom.xml
+++ b/pom.xml
@@ -126,7 +126,7 @@
6.0.3
1.5.4.Final-format-001
1.6.0.Final
- 2.2.6
+ 3.0.4
15.4
1.6.1
2.0
diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FipsDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FipsDistTest.java
index 3e441e570ed..151c4f72a6c 100644
--- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FipsDistTest.java
+++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FipsDistTest.java
@@ -21,7 +21,7 @@ import java.nio.file.Path;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
-import org.keycloak.crypto.fips.KeycloakFipsSecurityProvider;
+import org.keycloak.crypto.fips.FIPS1402Provider;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.RawDistOnly;
@@ -44,7 +44,7 @@ public class FipsDistTest {
cliResult.assertStarted();
// Not shown as FIPS is not a preview anymore
cliResult.assertMessageWasShownExactlyNumberOfTimes("Preview features enabled: fips:v1", 0);
- cliResult.assertMessage("KeycloakFipsSecurityProvider created: KC(" + BCFIPS_VERSION + ", FIPS-JVM: " + KeycloakFipsSecurityProvider.isSystemFipsEnabled() + ") version 1.0");
+ cliResult.assertMessage("FIPS1402Provider created: KC(" + BCFIPS_VERSION + ", FIPS-JVM: " + FIPS1402Provider.isSystemFipsEnabled() + ")");
});
}
@@ -56,7 +56,7 @@ public class FipsDistTest {
CLIResult cliResult = dist.run("start", "--fips-mode=strict");
cliResult.assertMessage("password must be at least 112 bits");
- cliResult.assertMessage("KeycloakFipsSecurityProvider created: KC(" + BCFIPS_VERSION + " Approved Mode, FIPS-JVM: " + KeycloakFipsSecurityProvider.isSystemFipsEnabled() + ") version 1.0");
+ cliResult.assertMessage("FIPS1402Provider created: KC(" + BCFIPS_VERSION + " Approved Mode, FIPS-JVM: " + FIPS1402Provider.isSystemFipsEnabled() + ")");
dist.setEnvVar("KC_BOOTSTRAP_ADMIN_PASSWORD", "adminadminadmin");
cliResult = dist.run("start", "--fips-mode=strict");
diff --git a/services/src/main/java/org/keycloak/keys/AbstractEcKeyProviderFactory.java b/services/src/main/java/org/keycloak/keys/AbstractEcKeyProviderFactory.java
index fc145594bd1..c0c5e3010f1 100644
--- a/services/src/main/java/org/keycloak/keys/AbstractEcKeyProviderFactory.java
+++ b/services/src/main/java/org/keycloak/keys/AbstractEcKeyProviderFactory.java
@@ -52,7 +52,7 @@ public abstract class AbstractEcKeyProviderFactory implem
public static KeyPair generateEcKeyPair(String keySpecName) {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
- SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom randomGen = new SecureRandom();
ECGenParameterSpec ecSpec = new ECGenParameterSpec(keySpecName);
keyGen.initialize(ecSpec, randomGen);
return keyGen.generateKeyPair();
diff --git a/services/src/main/java/org/keycloak/protocol/saml/DefaultSamlArtifactResolver.java b/services/src/main/java/org/keycloak/protocol/saml/DefaultSamlArtifactResolver.java
index dd5cdafd95d..d2c006ab006 100644
--- a/services/src/main/java/org/keycloak/protocol/saml/DefaultSamlArtifactResolver.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/DefaultSamlArtifactResolver.java
@@ -10,7 +10,6 @@ import org.keycloak.utils.StringUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Collections;
@@ -101,7 +100,7 @@ public class DefaultSamlArtifactResolver implements ArtifactResolver {
*/
public String createArtifact(String entityId) throws ArtifactResolverProcessingException {
try {
- SecureRandom handleGenerator = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom handleGenerator = new SecureRandom();
byte[] trimmedIndex = new byte[2];
byte[] source = ArtifactBindingUtils.computeArtifactBindingIdentifier(entityId);
@@ -118,8 +117,6 @@ public class DefaultSamlArtifactResolver implements ArtifactResolver {
byte[] artifact = bos.toByteArray();
return Base64.getEncoder().encodeToString(artifact);
- } catch (NoSuchAlgorithmException e) {
- throw new ArtifactResolverProcessingException("JVM does not support required cryptography algorithms: SHA-1/SHA1PRNG.", e);
} catch (IOException e) {
throw new ArtifactResolverProcessingException(e);
}
diff --git a/services/src/test/java/org/keycloak/protocol/saml/SamlEncryptionTest.java b/services/src/test/java/org/keycloak/protocol/saml/SamlEncryptionTest.java
index b5b1ba5c990..e89e4d6ca67 100644
--- a/services/src/test/java/org/keycloak/protocol/saml/SamlEncryptionTest.java
+++ b/services/src/test/java/org/keycloak/protocol/saml/SamlEncryptionTest.java
@@ -85,18 +85,13 @@ public class SamlEncryptionTest {
@BeforeClass
public static void beforeClass() {
Cipher cipher = null;
- SecureRandom random = null;
try {
- // Apache santuario 2.2.3 needs to have SHA1PRNG (fixed in 3.0.2)
- // see: https://issues.apache.org/jira/browse/SANTUARIO-589
- random = SecureRandom.getInstance("SHA1PRNG");
// FIPS mode removes needed ciphers like "RSA/ECB/OAEPPadding"
cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
} catch (NoSuchAlgorithmException|NoSuchPaddingException e) {
// ignore
}
Assume.assumeNotNull("OAEPPadding not supported", cipher);
- Assume.assumeNotNull("SHA1PRNG required for Apache santuario xmlsec", random);
}
private void testEncryption(KeyPair pair, String alg, int keySize, String keyWrapAlg, String keyWrapHashMethod, String keyWrapMgf) throws Exception {
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestingOIDCEndpointsApplicationResource.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestingOIDCEndpointsApplicationResource.java
index 984166827ae..5a0a73ae8dc 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestingOIDCEndpointsApplicationResource.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestingOIDCEndpointsApplicationResource.java
@@ -190,7 +190,7 @@ public class TestingOIDCEndpointsApplicationResource {
private KeyPair generateEcdsaKey(String ecDomainParamName) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
- SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom randomGen = new SecureRandom();
ECGenParameterSpec ecSpec = new ECGenParameterSpec(ecDomainParamName);
keyGen.initialize(ecSpec, randomGen);
KeyPair keyPair = keyGen.generateKeyPair();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java
index 29714d4cabe..7a5caeda556 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/BasicSamlTest.java
@@ -469,17 +469,17 @@ public class BasicSamlTest extends AbstractSamlTest {
@Test
public void testEncryptionRsaOaep11Default() throws Exception {
- testEncryption(XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP_11, XMLCipher.SHA1, EncryptionConstants.MGF1_SHA1, XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP_11, "", "");
+ testEncryption(XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP_11, XMLCipher.SHA1, EncryptionConstants.MGF1_SHA1, XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP_11, "", EncryptionConstants.MGF1_SHA1);
}
@Test
public void testEncryptionRsaOaep() throws Exception {
- testEncryption(XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP, XMLCipher.SHA256, "");
+ testEncryption(XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP, XMLCipher.SHA256, "", XMLCipher.AES_256_GCM, XMLCipher.RSA_OAEP, XMLCipher.SHA256, EncryptionConstants.MGF1_SHA1);
}
@Test
public void testEncryptionRsaOaepLegacy() throws Exception {
- testEncryption(XMLCipher.AES_128, XMLCipher.RSA_OAEP, XMLCipher.SHA1, "", XMLCipher.AES_128, XMLCipher.RSA_OAEP, "", "");
+ testEncryption(XMLCipher.AES_128, XMLCipher.RSA_OAEP, XMLCipher.SHA1, "", XMLCipher.AES_128, XMLCipher.RSA_OAEP, "", EncryptionConstants.MGF1_SHA1);
}
@Test
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientPoliciesUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientPoliciesUtil.java
index e72a7f146ae..020f8f6c161 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientPoliciesUtil.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientPoliciesUtil.java
@@ -468,7 +468,7 @@ public final class ClientPoliciesUtil {
public static KeyPair generateEcdsaKey(String ecDomainParamName) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
- SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
+ SecureRandom randomGen = new SecureRandom();
ECGenParameterSpec ecSpec = new ECGenParameterSpec(ecDomainParamName);
keyGen.initialize(ecSpec, randomGen);
KeyPair keyPair = keyGen.generateKeyPair();