0
# Cryptography
1
2
Comprehensive cryptographic utilities including cipher executors, password encoders, certificate management, and key handling for secure operations.
3
4
## Core Imports
5
6
```java
7
import org.apereo.cas.util.cipher.AbstractCipherExecutor;
8
import org.apereo.cas.util.crypto.CipherExecutor;
9
import org.apereo.cas.util.crypto.EncodableCipher;
10
import org.apereo.cas.util.crypto.DecodableCipher;
11
import java.security.Key;
12
import java.security.PrivateKey;
13
import java.security.PublicKey;
14
```
15
16
## AbstractCipherExecutor
17
18
Abstract base class providing common operations for signing and encrypting objects.
19
20
```java { .api }
21
public abstract class AbstractCipherExecutor<T, R> implements CipherExecutor<T, R> {
22
23
// Key extraction utilities
24
public static PrivateKey extractPrivateKeyFromResource(String signingSecretKey);
25
public static PublicKey extractPublicKeyFromResource(String secretKeyToUse);
26
27
// Core operations (inherited from CipherExecutor interface)
28
@Override
29
public boolean isEnabled();
30
31
@Override
32
public Key getSigningKey();
33
34
@Override
35
public CipherExecutor<T, ?> withSigningDisabled();
36
37
// Encoding/Decoding operations (from EncodableCipher and DecodableCipher interfaces)
38
// Must be implemented by concrete subclasses
39
@Override
40
public T encode(R value, Object[] parameters);
41
42
@Override
43
public R decode(T value, Object[] parameters);
44
45
@Override
46
public T encode(R value);
47
48
@Override
49
public R decode(T value);
50
}
51
```
52
53
### Usage Examples
54
55
**Creating custom cipher executors:**
56
```java
57
public class TokenCipherExecutor extends AbstractCipherExecutor<String, String> {
58
59
public TokenCipherExecutor(String secretKey, String signingKey) {
60
setSecretKeyEncryption(secretKey);
61
setSigningKey(signingKey);
62
}
63
64
@Override
65
public String encode(String value, Object[] parameters) {
66
if (!isEnabled()) {
67
return value;
68
}
69
70
// Encrypt the value
71
String encrypted = encryptValue(value);
72
73
// Sign the encrypted value
74
return sign(encrypted);
75
}
76
77
@Override
78
public String decode(String value, Object[] parameters) {
79
if (!isEnabled()) {
80
return value;
81
}
82
83
// Verify signature first
84
if (!verifySignature(value, value)) {
85
throw new DecryptionException("Invalid signature");
86
}
87
88
// Extract and decrypt
89
String encrypted = extractEncryptedValue(value);
90
return decryptValue(encrypted);
91
}
92
}
93
```
94
95
**Key management:**
96
```java
97
// Extract keys from resources
98
PrivateKey privateKey = AbstractCipherExecutor.extractPrivateKeyFromResource("file:private.pem");
99
PublicKey publicKey = AbstractCipherExecutor.extractPublicKeyFromResource("classpath:public.pem");
100
101
// Use in cipher configuration
102
TokenCipherExecutor cipher = new TokenCipherExecutor();
103
cipher.setSigningKey(privateKey);
104
cipher.setEncryptionKey(publicKey);
105
```
106
107
## Cipher Executor Implementations
108
109
### DefaultTicketCipherExecutor
110
111
Default implementation for ticket encryption and signing.
112
113
```java { .api }
114
public class DefaultTicketCipherExecutor extends BaseStringCipherExecutor {
115
116
public DefaultTicketCipherExecutor(String secretKeyEncryption,
117
String secretKeySigning,
118
String alg,
119
int signingKeySize,
120
int encryptionKeySize);
121
122
public DefaultTicketCipherExecutor(String secretKeyEncryption,
123
String secretKeySigning,
124
boolean enableEncryption,
125
boolean enableSigning,
126
int signingKeySize,
127
int encryptionKeySize);
128
}
129
```
130
131
### JasyptNumberCipherExecutor
132
133
Jasypt-based number encryption for sensitive numeric data.
134
135
```java { .api }
136
public class JasyptNumberCipherExecutor extends AbstractCipherExecutor<Number, Number> {
137
138
public JasyptNumberCipherExecutor(String secretKey, String algorithm);
139
140
@Override
141
public Number encode(Number value, Object[] parameters);
142
143
@Override
144
public Number decode(Number value, Object[] parameters);
145
}
146
```
147
148
### JsonWebKeySetStringCipherExecutor
149
150
JWT-based string cipher using JSON Web Key Sets.
151
152
```java { .api }
153
public class JsonWebKeySetStringCipherExecutor extends BaseStringCipherExecutor {
154
155
public JsonWebKeySetStringCipherExecutor(Resource jwksResource);
156
public JsonWebKeySetStringCipherExecutor(String jwksJson);
157
158
// Inherits encode/decode from BaseStringCipherExecutor
159
}
160
```
161
162
### RsaKeyPairCipherExecutor
163
164
RSA key pair cipher for asymmetric encryption operations.
165
166
```java { .api }
167
public class RsaKeyPairCipherExecutor extends AbstractCipherExecutor<String, String> {
168
169
public RsaKeyPairCipherExecutor(PrivateKey privateKey, PublicKey publicKey);
170
public RsaKeyPairCipherExecutor(String privateKeyLocation, String publicKeyLocation);
171
172
@Override
173
public String encode(String value, Object[] parameters);
174
175
@Override
176
public String decode(String value, Object[] parameters);
177
}
178
```
179
180
### Usage Examples
181
182
**Ticket encryption:**
183
```java
184
// Configure ticket cipher
185
DefaultTicketCipherExecutor ticketCipher = new DefaultTicketCipherExecutor(
186
"encryption-secret-key-32-chars-min", // Encryption key
187
"signing-secret-key-64-chars-minimum", // Signing key
188
"AES", // Algorithm
189
512, // Signing key size
190
256 // Encryption key size
191
);
192
193
// Encrypt/decrypt tickets
194
String ticket = "TGT-123-example-ticket";
195
String encrypted = ticketCipher.encode(ticket);
196
String decrypted = ticketCipher.decode(encrypted);
197
```
198
199
**Number encryption:**
200
```java
201
// Jasypt number cipher
202
JasyptNumberCipherExecutor numberCipher = new JasyptNumberCipherExecutor(
203
"secret-key",
204
"PBEWithMD5AndTripleDES"
205
);
206
207
// Encrypt sensitive numbers
208
Long userId = 12345L;
209
Number encrypted = numberCipher.encode(userId);
210
Long decrypted = (Long) numberCipher.decode(encrypted);
211
```
212
213
**RSA asymmetric encryption:**
214
```java
215
// RSA cipher with key files
216
RsaKeyPairCipherExecutor rsaCipher = new RsaKeyPairCipherExecutor(
217
"file:/path/to/private.pem",
218
"file:/path/to/public.pem"
219
);
220
221
// Or with key objects
222
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
223
generator.initialize(2048);
224
KeyPair keyPair = generator.generateKeyPair();
225
226
RsaKeyPairCipherExecutor rsaCipher2 = new RsaKeyPairCipherExecutor(
227
keyPair.getPrivate(),
228
keyPair.getPublic()
229
);
230
231
// Encrypt/decrypt data
232
String sensitive = "confidential-data";
233
String encrypted = rsaCipher.encode(sensitive);
234
String decrypted = rsaCipher.decode(encrypted);
235
```
236
237
## CipherExecutorUtils
238
239
Utility methods for cipher operations and key management.
240
241
```java { .api }
242
@UtilityClass
243
public class CipherExecutorUtils {
244
245
// Key generation utilities
246
public static String generateSecretKey(int keySize);
247
public static Key generateKey(String algorithm, int keySize);
248
249
// Cipher configuration
250
public static CipherExecutor<String, String> newStringCipherExecutor(
251
String encryptionKey,
252
String signingKey
253
);
254
255
// Validation utilities
256
public static boolean isEnabled(CipherExecutor<?, ?> cipher);
257
public static void validateCipherConfiguration(CipherExecutor<?, ?> cipher);
258
}
259
```
260
261
## BasicIdentifiableKey
262
263
Basic implementation for identifiable cryptographic keys.
264
265
```java { .api }
266
public class BasicIdentifiableKey implements IdentifiableKey {
267
268
private final String id;
269
private final Key key;
270
271
public BasicIdentifiableKey(String id, Key key);
272
273
@Override
274
public String getId();
275
276
@Override
277
public Key getKey();
278
279
@Override
280
public String getAlgorithm();
281
}
282
```
283
284
### Usage Examples
285
286
**Key management with identifiers:**
287
```java
288
// Create identifiable keys
289
SecretKey aesKey = generateAESKey();
290
BasicIdentifiableKey identifiableKey = new BasicIdentifiableKey("key-2024-01", aesKey);
291
292
// Use in key stores or rotation scenarios
293
Map<String, IdentifiableKey> keyStore = new HashMap<>();
294
keyStore.put(identifiableKey.getId(), identifiableKey);
295
296
// Retrieve by ID for cipher operations
297
IdentifiableKey currentKey = keyStore.get("key-2024-01");
298
CipherExecutor cipher = createCipherWithKey(currentKey.getKey());
299
```
300
301
## Certificate Utilities (CertUtils)
302
303
Certificate management utilities for X.509 operations.
304
305
```java { .api }
306
@UtilityClass
307
public class CertUtils {
308
309
// Certificate reading
310
public static X509Certificate readCertificate(Resource resource);
311
public static X509Certificate readCertificate(InputStream inputStream);
312
public static X509Certificate readCertificate(String certificateString);
313
314
// Certificate validation
315
public static boolean isCertificateValid(X509Certificate cert);
316
public static boolean isCertificateValid(X509Certificate cert, Date validationDate);
317
318
// Certificate information extraction
319
public static String getSubjectDN(X509Certificate cert);
320
public static String getIssuerDN(X509Certificate cert);
321
public static Date getNotBefore(X509Certificate cert);
322
public static Date getNotAfter(X509Certificate cert);
323
}
324
```
325
326
### Usage Examples
327
328
**Certificate operations:**
329
```java
330
// Read certificates from various sources
331
Resource certResource = new ClassPathResource("server.crt");
332
X509Certificate cert = CertUtils.readCertificate(certResource);
333
334
// Validate certificates
335
boolean isValid = CertUtils.isCertificateValid(cert);
336
boolean isValidAtDate = CertUtils.isCertificateValid(cert, new Date());
337
338
// Extract certificate information
339
String subject = CertUtils.getSubjectDN(cert);
340
String issuer = CertUtils.getIssuerDN(cert);
341
Date expires = CertUtils.getNotAfter(cert);
342
343
// Use in SSL configuration
344
if (CertUtils.isCertificateValid(cert)) {
345
configureSSLContext(cert);
346
} else {
347
log.warn("Certificate expired: {}", CertUtils.getNotAfter(cert));
348
}
349
```
350
351
## Password Encoders
352
353
### DefaultPasswordEncoder
354
355
Default password encoding implementation with configurable algorithms.
356
357
```java { .api }
358
public class DefaultPasswordEncoder implements PasswordEncoder {
359
360
public DefaultPasswordEncoder(String encodingAlgorithm);
361
public DefaultPasswordEncoder(String encodingAlgorithm, String characterEncoding);
362
363
@Override
364
public String encode(CharSequence rawPassword);
365
366
@Override
367
public boolean matches(CharSequence rawPassword, String encodedPassword);
368
}
369
```
370
371
### GlibcCryptPasswordEncoder
372
373
Glibc crypt-compatible password encoder for Unix-style password hashing.
374
375
```java { .api }
376
public class GlibcCryptPasswordEncoder implements PasswordEncoder {
377
378
public GlibcCryptPasswordEncoder();
379
public GlibcCryptPasswordEncoder(String saltPrefix);
380
381
@Override
382
public String encode(CharSequence rawPassword);
383
384
@Override
385
public boolean matches(CharSequence rawPassword, String encodedPassword);
386
}
387
```
388
389
### Usage Examples
390
391
**Password encoding:**
392
```java
393
// Default password encoder with SHA-256
394
DefaultPasswordEncoder encoder = new DefaultPasswordEncoder("SHA-256", "UTF-8");
395
String encoded = encoder.encode("user-password");
396
boolean matches = encoder.matches("user-password", encoded);
397
398
// Glibc crypt encoder for Unix compatibility
399
GlibcCryptPasswordEncoder cryptEncoder = new GlibcCryptPasswordEncoder("$6$"); // SHA-512
400
String crypted = cryptEncoder.encode("user-password");
401
boolean cryptMatches = cryptEncoder.matches("user-password", crypted);
402
403
// Use in authentication
404
@Service
405
public class AuthenticationService {
406
407
private final PasswordEncoder passwordEncoder = new DefaultPasswordEncoder("SHA-256");
408
409
public boolean authenticate(String username, String password) {
410
User user = userRepository.findByUsername(username);
411
return user != null && passwordEncoder.matches(password, user.getPasswordHash());
412
}
413
}
414
```
415
416
## Key Factory Beans
417
418
Spring factory beans for key management in application contexts.
419
420
### PrivateKeyFactoryBean
421
422
```java { .api }
423
public class PrivateKeyFactoryBean implements FactoryBean<PrivateKey> {
424
425
public PrivateKeyFactoryBean(Resource location, String algorithm);
426
427
@Override
428
public PrivateKey getObject();
429
430
@Override
431
public Class<?> getObjectType();
432
433
@Override
434
public boolean isSingleton();
435
}
436
```
437
438
### PublicKeyFactoryBean
439
440
```java { .api }
441
public class PublicKeyFactoryBean implements FactoryBean<PublicKey> {
442
443
public PublicKeyFactoryBean(Resource location, String algorithm);
444
445
@Override
446
public PublicKey getObject();
447
448
@Override
449
public Class<?> getObjectType();
450
451
@Override
452
public boolean isSingleton();
453
}
454
```
455
456
### Usage Examples
457
458
**Spring configuration with key factory beans:**
459
```java
460
@Configuration
461
public class CryptoConfiguration {
462
463
@Bean
464
public PrivateKeyFactoryBean signingPrivateKey() {
465
return new PrivateKeyFactoryBean(
466
new ClassPathResource("signing-private.pem"),
467
"RSA"
468
);
469
}
470
471
@Bean
472
public PublicKeyFactoryBean signingPublicKey() {
473
return new PublicKeyFactoryBean(
474
new ClassPathResource("signing-public.pem"),
475
"RSA"
476
);
477
}
478
479
@Bean
480
public CipherExecutor<String, String> jwtCipher(
481
@Qualifier("signingPrivateKey") PrivateKey privateKey,
482
@Qualifier("signingPublicKey") PublicKey publicKey) {
483
484
return new RsaKeyPairCipherExecutor(privateKey, publicKey);
485
}
486
}
487
```
488
489
## DecryptionException
490
491
Exception thrown during decryption failures.
492
493
```java { .api }
494
public class DecryptionException extends RuntimeException {
495
496
public DecryptionException(String message);
497
public DecryptionException(String message, Throwable cause);
498
public DecryptionException(Throwable cause);
499
}
500
```
501
502
### Usage Example
503
504
**Exception handling in cipher operations:**
505
```java
506
public class SecureDataService {
507
508
private final CipherExecutor<String, String> cipher;
509
510
public String processSecureData(String encryptedData) {
511
try {
512
return cipher.decode(encryptedData);
513
} catch (DecryptionException e) {
514
log.error("Failed to decrypt data", e);
515
throw new ServiceException("Invalid encrypted data", e);
516
}
517
}
518
}
519
```