0
# Cryptographic Utilities
1
2
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.
3
4
## Crypto Integration
5
6
The `CryptoIntegration` class serves as the central integration point for crypto providers.
7
8
```java { .api }
9
public class CryptoIntegration {
10
/**
11
* Initializes crypto integration with the specified class loader
12
*/
13
public static void init(ClassLoader classLoader);
14
15
/**
16
* Gets the current crypto provider
17
*/
18
public static CryptoProvider getProvider();
19
20
/**
21
* Sets the crypto provider
22
*/
23
public static void setProvider(CryptoProvider provider);
24
25
/**
26
* Dumps Java security providers information for debugging
27
*/
28
public static String dumpJavaSecurityProviders();
29
30
/**
31
* Dumps security properties information for debugging
32
*/
33
public static String dumpSecurityProperties();
34
}
35
```
36
37
### Usage Examples
38
39
```java
40
// Initialize crypto integration
41
CryptoIntegration.init(Thread.currentThread().getContextClassLoader());
42
43
// Get current provider
44
CryptoProvider provider = CryptoIntegration.getProvider();
45
46
// Debug security configuration
47
String providersInfo = CryptoIntegration.dumpJavaSecurityProviders();
48
String securityProps = CryptoIntegration.dumpSecurityProperties();
49
logger.debug("Security providers: {}", providersInfo);
50
```
51
52
## Crypto Provider Interface
53
54
The `CryptoProvider` interface provides abstraction for cryptographic operations supporting both FIPS and non-FIPS implementations.
55
56
### Core Provider Methods
57
58
```java { .api }
59
public interface CryptoProvider {
60
/**
61
* Gets BouncyCastle provider instance
62
*/
63
Provider getBouncyCastleProvider();
64
65
/**
66
* Gets provider priority order
67
*/
68
int order();
69
70
/**
71
* Gets algorithm-specific provider
72
*/
73
<T> T getAlgorithmProvider(Class<T> clazz, String algorithm);
74
}
75
```
76
77
### Utility Providers
78
79
```java { .api }
80
public interface CryptoProvider {
81
/**
82
* Gets certificate utilities provider
83
*/
84
CertificateUtilsProvider getCertificateUtils();
85
86
/**
87
* Gets PEM utilities provider
88
*/
89
PemUtilsProvider getPemUtils();
90
91
/**
92
* Gets OCSP prover
93
*/
94
<T> T getOCSPProver(Class<T> clazz);
95
96
/**
97
* Gets user identity extractor provider
98
*/
99
UserIdentityExtractorProvider getIdentityExtractorProvider();
100
101
/**
102
* Gets ECDSA crypto provider
103
*/
104
ECDSACryptoProvider getEcdsaCryptoProvider();
105
}
106
```
107
108
### Key and Certificate Operations
109
110
```java { .api }
111
public interface CryptoProvider {
112
/**
113
* Creates elliptic curve parameters for specified curve
114
*/
115
ECParameterSpec createECParams(String curveName);
116
117
/**
118
* Gets key pair generator for specified algorithm
119
*/
120
KeyPairGenerator getKeyPairGen(String algorithm);
121
122
/**
123
* Gets key factory for specified algorithm
124
*/
125
KeyFactory getKeyFactory(String algorithm);
126
127
/**
128
* Gets secret key factory for specified algorithm
129
*/
130
SecretKeyFactory getSecretKeyFact(String keyAlgorithm);
131
132
/**
133
* Gets keystore for specified format
134
*/
135
KeyStore getKeyStore(KeystoreFormat format);
136
137
/**
138
* Gets supported keystore types
139
*/
140
Stream<KeystoreFormat> getSupportedKeyStoreTypes();
141
142
/**
143
* Gets X.509 certificate factory
144
*/
145
CertificateFactory getX509CertFactory();
146
}
147
```
148
149
### Cipher and Security Operations
150
151
```java { .api }
152
public interface CryptoProvider {
153
/**
154
* Gets AES CBC cipher instance
155
*/
156
Cipher getAesCbcCipher();
157
158
/**
159
* Gets AES GCM cipher instance
160
*/
161
Cipher getAesGcmCipher();
162
163
/**
164
* Gets certificate store with collection parameters
165
*/
166
CertStore getCertStore(CollectionCertStoreParameters params);
167
168
/**
169
* Gets certificate path builder
170
*/
171
CertPathBuilder getCertPathBuilder();
172
173
/**
174
* Gets signature instance for specified algorithm
175
*/
176
Signature getSignature(String sigAlgName);
177
178
/**
179
* Wraps SSL socket factory for truststore support
180
*/
181
SSLSocketFactory wrapFactoryForTruststore(SSLSocketFactory delegate);
182
183
/**
184
* Gets supported RSA key sizes (default: ["1024", "2048", "4096"])
185
*/
186
String[] getSupportedRsaKeySizes();
187
}
188
```
189
190
## FIPS Mode Configuration
191
192
The `FipsMode` enum configures FIPS (Federal Information Processing Standard) compliance levels.
193
194
```java { .api }
195
public enum FipsMode {
196
/**
197
* Non-strict FIPS mode - FIPS algorithms preferred but non-FIPS allowed
198
*/
199
NON_STRICT("org.keycloak.crypto.fips.FIPS1402Provider"),
200
201
/**
202
* Strict FIPS mode - Only FIPS-approved algorithms allowed
203
*/
204
STRICT("org.keycloak.crypto.fips.Fips1402StrictCryptoProvider"),
205
206
/**
207
* FIPS disabled - Standard cryptographic providers
208
*/
209
DISABLED("org.keycloak.crypto.def.DefaultCryptoProvider");
210
211
/**
212
* Checks if FIPS is enabled (NON_STRICT or STRICT)
213
*/
214
public boolean isFipsEnabled();
215
216
/**
217
* Gets the provider class name for this FIPS mode
218
*/
219
public String getProviderClassName();
220
221
/**
222
* Gets enum value from option name
223
*/
224
public static FipsMode valueOfOption(String name);
225
226
/**
227
* Returns the option name
228
*/
229
public String toString();
230
}
231
```
232
233
### Usage Examples
234
235
```java
236
// Configure FIPS mode
237
FipsMode fipsMode = FipsMode.STRICT;
238
if (fipsMode.isFipsEnabled()) {
239
logger.info("FIPS mode enabled: {}", fipsMode);
240
}
241
242
// Load FIPS provider
243
String providerClass = fipsMode.getProviderClassName();
244
CryptoProvider provider = loadCryptoProvider(providerClass);
245
246
// Parse FIPS mode from configuration
247
String configValue = "non-strict";
248
FipsMode mode = FipsMode.valueOfOption(configValue);
249
```
250
251
## Certificate Utilities Provider
252
253
The `CertificateUtilsProvider` interface provides certificate generation and processing utilities.
254
255
```java { .api }
256
public interface CertificateUtilsProvider {
257
/**
258
* CRL Distribution Points OID constant
259
*/
260
String CRL_DISTRIBUTION_POINTS_OID = "2.5.29.31";
261
262
/**
263
* Generates a V3 certificate signed by a CA
264
* @param keyPair The key pair for the new certificate
265
* @param caPrivateKey The CA's private key for signing
266
* @param caCert The CA certificate
267
* @param subject The subject DN for the new certificate
268
* @return The generated X509Certificate
269
* @throws Exception If certificate generation fails
270
*/
271
X509Certificate generateV3Certificate(
272
KeyPair keyPair,
273
PrivateKey caPrivateKey,
274
X509Certificate caCert,
275
String subject
276
) throws Exception;
277
278
/**
279
* Generates a V1 self-signed certificate
280
*/
281
X509Certificate generateV1SelfSignedCertificate(KeyPair caKeyPair, String subject);
282
283
/**
284
* Generates a V1 self-signed certificate with serial number
285
*/
286
X509Certificate generateV1SelfSignedCertificate(
287
KeyPair caKeyPair,
288
String subject,
289
BigInteger serialNumber
290
);
291
292
/**
293
* Generates a V1 self-signed certificate with serial number and validity period
294
*/
295
X509Certificate generateV1SelfSignedCertificate(
296
KeyPair caKeyPair,
297
String subject,
298
BigInteger serialNumber,
299
Date validityEndDate
300
);
301
302
/**
303
* Gets certificate policy list from certificate
304
*/
305
List<String> getCertificatePolicyList(X509Certificate cert) throws GeneralSecurityException;
306
307
/**
308
* Gets CRL distribution points from certificate
309
*/
310
List<String> getCRLDistributionPoints(X509Certificate cert) throws IOException;
311
312
/**
313
* Creates test certificate for services
314
*/
315
X509Certificate createServicesTestCertificate(
316
String dn,
317
Date startDate,
318
Date expiryDate,
319
KeyPair keyPair,
320
String... certificatePolicyOid
321
);
322
}
323
```
324
325
## PEM Utilities Provider
326
327
The `PemUtilsProvider` abstract class provides PEM format encoding and decoding utilities.
328
329
```java { .api }
330
public abstract class PemUtilsProvider {
331
/**
332
* Decodes X509 certificate from PEM format
333
*/
334
public X509Certificate decodeCertificate(String cert);
335
336
/**
337
* Decodes public key from PEM format (defaults to RSA)
338
*/
339
public PublicKey decodePublicKey(String pem);
340
341
/**
342
* Decodes public key from PEM format with specified type
343
*/
344
public PublicKey decodePublicKey(String pem, String type);
345
346
/**
347
* Decodes private key from PEM format
348
*/
349
public abstract PrivateKey decodePrivateKey(String pem);
350
351
/**
352
* Encodes key to PEM format
353
*/
354
public String encodeKey(Key key);
355
356
/**
357
* Encodes certificate to PEM format
358
*/
359
public String encodeCertificate(Certificate certificate);
360
361
/**
362
* Converts PEM to DER format
363
*/
364
public byte[] pemToDer(String pem);
365
366
/**
367
* Removes PEM headers and footers
368
*/
369
public String removeBeginEnd(String pem);
370
371
/**
372
* Generates certificate chain thumbprint
373
*/
374
public String generateThumbprint(String[] certChain, String encoding) throws NoSuchAlgorithmException;
375
376
/**
377
* Encodes object to PEM format
378
*/
379
public abstract String encode(Object obj);
380
}
381
```
382
383
## ECDSA Crypto Provider
384
385
The `ECDSACryptoProvider` interface provides ECDSA-specific cryptographic operations.
386
387
```java { .api }
388
public interface ECDSACryptoProvider {
389
/**
390
* Converts concatenated R||S signature to ASN.1 DER format
391
*/
392
byte[] concatenatedRSToASN1DER(byte[] signature, int signLength) throws IOException;
393
394
/**
395
* Converts ASN.1 DER signature to concatenated R||S format
396
*/
397
byte[] asn1derToConcatenatedRS(byte[] derEncodedSignatureValue, int signLength) throws IOException;
398
399
/**
400
* Derives public key from private key
401
*/
402
ECPublicKey getPublicFromPrivate(ECPrivateKey ecPrivateKey);
403
}
404
```
405
406
## User Identity Extraction
407
408
### UserIdentityExtractor Interface
409
410
```java { .api }
411
public interface UserIdentityExtractor {
412
/**
413
* Extracts user identity from certificate chain
414
*/
415
Object extractUserIdentity(X509Certificate[] certs);
416
}
417
```
418
419
### UserIdentityExtractorProvider
420
421
```java { .api }
422
public abstract class UserIdentityExtractorProvider {
423
/**
424
* Creates OR builder for combining extractors
425
*/
426
public OrBuilder either(UserIdentityExtractor extractor);
427
428
/**
429
* Gets certificate PEM identity extractor
430
*/
431
public UserIdentityExtractor getCertificatePemIdentityExtractor();
432
433
/**
434
* Gets pattern-based identity extractor
435
*/
436
public UserIdentityExtractor getPatternIdentityExtractor(
437
String pattern,
438
Function<X509Certificate[], String> valueToMatch
439
);
440
441
/**
442
* Gets X500 name extractor
443
*/
444
public abstract UserIdentityExtractor getX500NameExtractor(
445
String identifier,
446
Function<X509Certificate[], Principal> x500Name
447
);
448
449
/**
450
* Gets subject alternative name extractor
451
*/
452
public abstract SubjectAltNameExtractor getSubjectAltNameExtractor(int generalName);
453
}
454
```
455
456
## Crypto Constants
457
458
```java { .api }
459
public class CryptoConstants {
460
// JWE Algorithm Constants
461
public static final String A128KW = "A128KW";
462
public static final String RSA1_5 = "RSA1_5";
463
public static final String RSA_OAEP = "RSA-OAEP";
464
public static final String RSA_OAEP_256 = "RSA-OAEP-256";
465
public static final String ECDH_ES = "ECDH-ES";
466
public static final String ECDH_ES_A128KW = "ECDH-ES+A128KW";
467
public static final String ECDH_ES_A192KW = "ECDH-ES+A192KW";
468
public static final String ECDH_ES_A256KW = "ECDH-ES+A256KW";
469
470
// Provider Constants
471
public static final String BC_PROVIDER_ID = "BC"; // Non-FIPS BouncyCastle
472
public static final String BCFIPS_PROVIDER_ID = "BCFIPS"; // FIPS BouncyCastle
473
}
474
```
475
476
## Usage Examples
477
478
### Complete Crypto Setup
479
480
```java
481
// Initialize crypto system
482
CryptoIntegration.init(ClassLoader.getSystemClassLoader());
483
484
// Configure FIPS mode
485
FipsMode fipsMode = FipsMode.STRICT;
486
if (fipsMode.isFipsEnabled()) {
487
// Set appropriate FIPS provider
488
String providerClass = fipsMode.getProviderClassName();
489
// Load and configure FIPS provider
490
}
491
492
// Get crypto provider
493
CryptoProvider provider = CryptoIntegration.getProvider();
494
495
// Generate key pair
496
KeyPairGenerator keyGen = provider.getKeyPairGen("RSA");
497
keyGen.initialize(2048);
498
KeyPair keyPair = keyGen.generateKeyPair();
499
500
// Create self-signed certificate
501
CertificateUtilsProvider certUtils = provider.getCertificateUtils();
502
X509Certificate cert = certUtils.generateV1SelfSignedCertificate(
503
keyPair,
504
"CN=test.example.com"
505
);
506
```
507
508
### PEM Operations
509
510
```java
511
CryptoProvider provider = CryptoIntegration.getProvider();
512
PemUtilsProvider pemUtils = provider.getPemUtils();
513
514
// Encode certificate to PEM
515
String pemCert = pemUtils.encodeCertificate(certificate);
516
517
// Decode certificate from PEM
518
X509Certificate cert = pemUtils.decodeCertificate(pemString);
519
520
// Encode key to PEM
521
String pemKey = pemUtils.encodeKey(privateKey);
522
523
// Decode private key from PEM
524
PrivateKey key = pemUtils.decodePrivateKey(pemString);
525
```
526
527
### ECDSA Operations
528
529
```java
530
CryptoProvider provider = CryptoIntegration.getProvider();
531
ECDSACryptoProvider ecdsaProvider = provider.getEcdsaCryptoProvider();
532
533
// Convert signature formats
534
byte[] derSignature = ecdsaProvider.concatenatedRSToASN1DER(rsSignature, 64);
535
byte[] rsSignature = ecdsaProvider.asn1derToConcatenatedRS(derSignature, 64);
536
537
// Derive public key from private key
538
ECPublicKey publicKey = ecdsaProvider.getPublicFromPrivate(privateKey);
539
```