Common library and dependencies shared with server and all adapters for the Keycloak identity and access management system
—
This document covers the cryptographic utilities in the org.keycloak.common.crypto package that provide abstraction layers for cryptographic operations, supporting both FIPS and non-FIPS modes.
The CryptoIntegration class serves as the central integration point for crypto providers.
public class CryptoIntegration {
/**
* Initializes crypto integration with the specified class loader
*/
public static void init(ClassLoader classLoader);
/**
* Gets the current crypto provider
*/
public static CryptoProvider getProvider();
/**
* Sets the crypto provider
*/
public static void setProvider(CryptoProvider provider);
/**
* Dumps Java security providers information for debugging
*/
public static String dumpJavaSecurityProviders();
/**
* Dumps security properties information for debugging
*/
public static String dumpSecurityProperties();
}// Initialize crypto integration
CryptoIntegration.init(Thread.currentThread().getContextClassLoader());
// Get current provider
CryptoProvider provider = CryptoIntegration.getProvider();
// Debug security configuration
String providersInfo = CryptoIntegration.dumpJavaSecurityProviders();
String securityProps = CryptoIntegration.dumpSecurityProperties();
logger.debug("Security providers: {}", providersInfo);The CryptoProvider interface provides abstraction for cryptographic operations supporting both FIPS and non-FIPS implementations.
public interface CryptoProvider {
/**
* Gets BouncyCastle provider instance
*/
Provider getBouncyCastleProvider();
/**
* Gets provider priority order
*/
int order();
/**
* Gets algorithm-specific provider
*/
<T> T getAlgorithmProvider(Class<T> clazz, String algorithm);
}public interface CryptoProvider {
/**
* Gets certificate utilities provider
*/
CertificateUtilsProvider getCertificateUtils();
/**
* Gets PEM utilities provider
*/
PemUtilsProvider getPemUtils();
/**
* Gets OCSP prover
*/
<T> T getOCSPProver(Class<T> clazz);
/**
* Gets user identity extractor provider
*/
UserIdentityExtractorProvider getIdentityExtractorProvider();
/**
* Gets ECDSA crypto provider
*/
ECDSACryptoProvider getEcdsaCryptoProvider();
}public interface CryptoProvider {
/**
* Creates elliptic curve parameters for specified curve
*/
ECParameterSpec createECParams(String curveName);
/**
* Gets key pair generator for specified algorithm
*/
KeyPairGenerator getKeyPairGen(String algorithm);
/**
* Gets key factory for specified algorithm
*/
KeyFactory getKeyFactory(String algorithm);
/**
* Gets secret key factory for specified algorithm
*/
SecretKeyFactory getSecretKeyFact(String keyAlgorithm);
/**
* Gets keystore for specified format
*/
KeyStore getKeyStore(KeystoreFormat format);
/**
* Gets supported keystore types
*/
Stream<KeystoreFormat> getSupportedKeyStoreTypes();
/**
* Gets X.509 certificate factory
*/
CertificateFactory getX509CertFactory();
}public interface CryptoProvider {
/**
* Gets AES CBC cipher instance
*/
Cipher getAesCbcCipher();
/**
* Gets AES GCM cipher instance
*/
Cipher getAesGcmCipher();
/**
* Gets certificate store with collection parameters
*/
CertStore getCertStore(CollectionCertStoreParameters params);
/**
* Gets certificate path builder
*/
CertPathBuilder getCertPathBuilder();
/**
* Gets signature instance for specified algorithm
*/
Signature getSignature(String sigAlgName);
/**
* Wraps SSL socket factory for truststore support
*/
SSLSocketFactory wrapFactoryForTruststore(SSLSocketFactory delegate);
/**
* Gets supported RSA key sizes (default: ["1024", "2048", "4096"])
*/
String[] getSupportedRsaKeySizes();
}The FipsMode enum configures FIPS (Federal Information Processing Standard) compliance levels.
public enum FipsMode {
/**
* Non-strict FIPS mode - FIPS algorithms preferred but non-FIPS allowed
*/
NON_STRICT("org.keycloak.crypto.fips.FIPS1402Provider"),
/**
* Strict FIPS mode - Only FIPS-approved algorithms allowed
*/
STRICT("org.keycloak.crypto.fips.Fips1402StrictCryptoProvider"),
/**
* FIPS disabled - Standard cryptographic providers
*/
DISABLED("org.keycloak.crypto.def.DefaultCryptoProvider");
/**
* Checks if FIPS is enabled (NON_STRICT or STRICT)
*/
public boolean isFipsEnabled();
/**
* Gets the provider class name for this FIPS mode
*/
public String getProviderClassName();
/**
* Gets enum value from option name
*/
public static FipsMode valueOfOption(String name);
/**
* Returns the option name
*/
public String toString();
}// Configure FIPS mode
FipsMode fipsMode = FipsMode.STRICT;
if (fipsMode.isFipsEnabled()) {
logger.info("FIPS mode enabled: {}", fipsMode);
}
// Load FIPS provider
String providerClass = fipsMode.getProviderClassName();
CryptoProvider provider = loadCryptoProvider(providerClass);
// Parse FIPS mode from configuration
String configValue = "non-strict";
FipsMode mode = FipsMode.valueOfOption(configValue);The CertificateUtilsProvider interface provides certificate generation and processing utilities.
public interface CertificateUtilsProvider {
/**
* CRL Distribution Points OID constant
*/
String CRL_DISTRIBUTION_POINTS_OID = "2.5.29.31";
/**
* Generates a V3 certificate signed by a CA
* @param keyPair The key pair for the new certificate
* @param caPrivateKey The CA's private key for signing
* @param caCert The CA certificate
* @param subject The subject DN for the new certificate
* @return The generated X509Certificate
* @throws Exception If certificate generation fails
*/
X509Certificate generateV3Certificate(
KeyPair keyPair,
PrivateKey caPrivateKey,
X509Certificate caCert,
String subject
) throws Exception;
/**
* Generates a V1 self-signed certificate
*/
X509Certificate generateV1SelfSignedCertificate(KeyPair caKeyPair, String subject);
/**
* Generates a V1 self-signed certificate with serial number
*/
X509Certificate generateV1SelfSignedCertificate(
KeyPair caKeyPair,
String subject,
BigInteger serialNumber
);
/**
* Generates a V1 self-signed certificate with serial number and validity period
*/
X509Certificate generateV1SelfSignedCertificate(
KeyPair caKeyPair,
String subject,
BigInteger serialNumber,
Date validityEndDate
);
/**
* Gets certificate policy list from certificate
*/
List<String> getCertificatePolicyList(X509Certificate cert) throws GeneralSecurityException;
/**
* Gets CRL distribution points from certificate
*/
List<String> getCRLDistributionPoints(X509Certificate cert) throws IOException;
/**
* Creates test certificate for services
*/
X509Certificate createServicesTestCertificate(
String dn,
Date startDate,
Date expiryDate,
KeyPair keyPair,
String... certificatePolicyOid
);
}The PemUtilsProvider abstract class provides PEM format encoding and decoding utilities.
public abstract class PemUtilsProvider {
/**
* Decodes X509 certificate from PEM format
*/
public X509Certificate decodeCertificate(String cert);
/**
* Decodes public key from PEM format (defaults to RSA)
*/
public PublicKey decodePublicKey(String pem);
/**
* Decodes public key from PEM format with specified type
*/
public PublicKey decodePublicKey(String pem, String type);
/**
* Decodes private key from PEM format
*/
public abstract PrivateKey decodePrivateKey(String pem);
/**
* Encodes key to PEM format
*/
public String encodeKey(Key key);
/**
* Encodes certificate to PEM format
*/
public String encodeCertificate(Certificate certificate);
/**
* Converts PEM to DER format
*/
public byte[] pemToDer(String pem);
/**
* Removes PEM headers and footers
*/
public String removeBeginEnd(String pem);
/**
* Generates certificate chain thumbprint
*/
public String generateThumbprint(String[] certChain, String encoding) throws NoSuchAlgorithmException;
/**
* Encodes object to PEM format
*/
public abstract String encode(Object obj);
}The ECDSACryptoProvider interface provides ECDSA-specific cryptographic operations.
public interface ECDSACryptoProvider {
/**
* Converts concatenated R||S signature to ASN.1 DER format
*/
byte[] concatenatedRSToASN1DER(byte[] signature, int signLength) throws IOException;
/**
* Converts ASN.1 DER signature to concatenated R||S format
*/
byte[] asn1derToConcatenatedRS(byte[] derEncodedSignatureValue, int signLength) throws IOException;
/**
* Derives public key from private key
*/
ECPublicKey getPublicFromPrivate(ECPrivateKey ecPrivateKey);
}public interface UserIdentityExtractor {
/**
* Extracts user identity from certificate chain
*/
Object extractUserIdentity(X509Certificate[] certs);
}public abstract class UserIdentityExtractorProvider {
/**
* Creates OR builder for combining extractors
*/
public OrBuilder either(UserIdentityExtractor extractor);
/**
* Gets certificate PEM identity extractor
*/
public UserIdentityExtractor getCertificatePemIdentityExtractor();
/**
* Gets pattern-based identity extractor
*/
public UserIdentityExtractor getPatternIdentityExtractor(
String pattern,
Function<X509Certificate[], String> valueToMatch
);
/**
* Gets X500 name extractor
*/
public abstract UserIdentityExtractor getX500NameExtractor(
String identifier,
Function<X509Certificate[], Principal> x500Name
);
/**
* Gets subject alternative name extractor
*/
public abstract SubjectAltNameExtractor getSubjectAltNameExtractor(int generalName);
}public class CryptoConstants {
// JWE Algorithm Constants
public static final String A128KW = "A128KW";
public static final String RSA1_5 = "RSA1_5";
public static final String RSA_OAEP = "RSA-OAEP";
public static final String RSA_OAEP_256 = "RSA-OAEP-256";
public static final String ECDH_ES = "ECDH-ES";
public static final String ECDH_ES_A128KW = "ECDH-ES+A128KW";
public static final String ECDH_ES_A192KW = "ECDH-ES+A192KW";
public static final String ECDH_ES_A256KW = "ECDH-ES+A256KW";
// Provider Constants
public static final String BC_PROVIDER_ID = "BC"; // Non-FIPS BouncyCastle
public static final String BCFIPS_PROVIDER_ID = "BCFIPS"; // FIPS BouncyCastle
}// Initialize crypto system
CryptoIntegration.init(ClassLoader.getSystemClassLoader());
// Configure FIPS mode
FipsMode fipsMode = FipsMode.STRICT;
if (fipsMode.isFipsEnabled()) {
// Set appropriate FIPS provider
String providerClass = fipsMode.getProviderClassName();
// Load and configure FIPS provider
}
// Get crypto provider
CryptoProvider provider = CryptoIntegration.getProvider();
// Generate key pair
KeyPairGenerator keyGen = provider.getKeyPairGen("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
// Create self-signed certificate
CertificateUtilsProvider certUtils = provider.getCertificateUtils();
X509Certificate cert = certUtils.generateV1SelfSignedCertificate(
keyPair,
"CN=test.example.com"
);CryptoProvider provider = CryptoIntegration.getProvider();
PemUtilsProvider pemUtils = provider.getPemUtils();
// Encode certificate to PEM
String pemCert = pemUtils.encodeCertificate(certificate);
// Decode certificate from PEM
X509Certificate cert = pemUtils.decodeCertificate(pemString);
// Encode key to PEM
String pemKey = pemUtils.encodeKey(privateKey);
// Decode private key from PEM
PrivateKey key = pemUtils.decodePrivateKey(pemString);CryptoProvider provider = CryptoIntegration.getProvider();
ECDSACryptoProvider ecdsaProvider = provider.getEcdsaCryptoProvider();
// Convert signature formats
byte[] derSignature = ecdsaProvider.concatenatedRSToASN1DER(rsSignature, 64);
byte[] rsSignature = ecdsaProvider.asn1derToConcatenatedRS(derSignature, 64);
// Derive public key from private key
ECPublicKey publicKey = ecdsaProvider.getPublicFromPrivate(privateKey);Install with Tessl CLI
npx tessl i tessl/maven-org-keycloak--keycloak-common