0
# JOSE Implementation
1
2
Complete JSON Object Signing and Encryption implementation including JWS (JSON Web Signature), JWE (JSON Web Encryption), and JWK (JSON Web Key) support according to RFC specifications.
3
4
## Capabilities
5
6
### JWS (JSON Web Signature)
7
8
JSON Web Signature implementation for creating and parsing signed JWT tokens.
9
10
```java { .api }
11
/**
12
* JWS token input and parsing utilities
13
*/
14
public class JWSInput {
15
/**
16
* Create JWS input from token string
17
* @param token JWS token string
18
*/
19
public JWSInput(String token) throws JWSInputException;
20
21
/**
22
* Get the JWS header
23
* @return JWS header object
24
*/
25
public JWSHeader getHeader();
26
27
/**
28
* Get the raw payload content
29
* @return Payload bytes
30
*/
31
public byte[] getContent();
32
33
/**
34
* Read JSON payload content as specified type
35
* @param type Target class type
36
* @return Deserialized object
37
* @throws IOException if JSON parsing fails
38
*/
39
public <T> T readJsonContent(Class<T> type) throws IOException;
40
41
/**
42
* Get the encoded signature input (header + payload)
43
* @return Base64URL encoded signature input
44
*/
45
public String getEncodedSignatureInput();
46
47
/**
48
* Get the signature bytes
49
* @return Signature bytes
50
*/
51
public byte[] getSignature();
52
53
/**
54
* Get the raw token string
55
* @return Original token string
56
*/
57
public String getWireString();
58
}
59
60
/**
61
* JWS header representation
62
*/
63
public class JWSHeader extends JOSEHeader {
64
/**
65
* Get the signature algorithm
66
* @return Algorithm identifier (e.g., "RS256", "ES256")
67
*/
68
public String getAlgorithm();
69
70
/**
71
* Get the key ID
72
* @return Key identifier
73
*/
74
public String getKeyId();
75
76
/**
77
* Get the token type
78
* @return Type value (usually "JWT")
79
*/
80
public String getType();
81
82
/**
83
* Get the content type
84
* @return Content type value
85
*/
86
public String getContentType();
87
88
/**
89
* Get critical header parameters
90
* @return Set of critical parameter names
91
*/
92
public Set<String> getCritical();
93
94
/**
95
* Get custom header parameter
96
* @param name Parameter name
97
* @return Parameter value
98
*/
99
public Object getOtherHeaderParameter(String name);
100
}
101
102
/**
103
* JWS token builder for creating signed tokens
104
*/
105
public class JWSBuilder {
106
/**
107
* Set JSON content as payload
108
* @param content Object to serialize as JSON
109
* @return JWSBuilder for chaining
110
*/
111
public JWSBuilder jsonContent(Object content);
112
113
/**
114
* Set raw content as payload
115
* @param content Raw payload bytes
116
* @return JWSBuilder for chaining
117
*/
118
public JWSBuilder content(byte[] content);
119
120
/**
121
* Set content type header
122
* @param contentType Content type value
123
* @return JWSBuilder for chaining
124
*/
125
public JWSBuilder contentType(String contentType);
126
127
/**
128
* Set token type header
129
* @param type Type value
130
* @return JWSBuilder for chaining
131
*/
132
public JWSBuilder type(String type);
133
134
/**
135
* Set key ID header
136
* @param kid Key identifier
137
* @return JWSBuilder for chaining
138
*/
139
public JWSBuilder kid(String kid);
140
141
/**
142
* Sign the token with the provided signer context
143
* @param signer Signature signer context
144
* @return Signed JWS token string
145
*/
146
public String sign(SignatureSignerContext signer);
147
}
148
```
149
150
### JWE (JSON Web Encryption)
151
152
JSON Web Encryption implementation for creating and parsing encrypted JWT tokens.
153
154
```java { .api }
155
/**
156
* JWE token representation and utilities
157
*/
158
public class JWE {
159
/**
160
* Create JWE from encrypted token string
161
* @param token JWE token string
162
*/
163
public JWE(String token) throws JWEException;
164
165
/**
166
* Get the JWE header
167
* @return JWE header object
168
*/
169
public JWEHeader getHeader();
170
171
/**
172
* Get the encrypted key
173
* @return Encrypted key bytes
174
*/
175
public byte[] getEncryptedKey();
176
177
/**
178
* Get the initialization vector
179
* @return IV bytes
180
*/
181
public byte[] getIv();
182
183
/**
184
* Get the encrypted content
185
* @return Encrypted content bytes
186
*/
187
public byte[] getEncryptedContent();
188
189
/**
190
* Get the authentication tag
191
* @return Authentication tag bytes
192
*/
193
public byte[] getTag();
194
}
195
196
/**
197
* JWE header representation
198
*/
199
public class JWEHeader extends JOSEHeader {
200
/**
201
* Get the key management algorithm
202
* @return Algorithm identifier (e.g., "RSA-OAEP", "A256KW")
203
*/
204
public String getAlgorithm();
205
206
/**
207
* Get the content encryption algorithm
208
* @return Encryption algorithm (e.g., "A256GCM", "A128CBC-HS256")
209
*/
210
public String getEncryptionAlgorithm();
211
212
/**
213
* Get the compression algorithm
214
* @return Compression algorithm or null
215
*/
216
public String getCompressionAlgorithm();
217
218
/**
219
* Get the key ID
220
* @return Key identifier
221
*/
222
public String getKeyId();
223
}
224
225
/**
226
* JWE constants for algorithms and parameters
227
*/
228
public interface JWEConstants {
229
// Key management algorithms
230
String RSA1_5 = "RSA1_5";
231
String RSA_OAEP = "RSA-OAEP";
232
String RSA_OAEP_256 = "RSA-OAEP-256";
233
String A128KW = "A128KW";
234
String A192KW = "A192KW";
235
String A256KW = "A256KW";
236
String DIR = "dir";
237
String A128GCMKW = "A128GCMKW";
238
String A192GCMKW = "A192GCMKW";
239
String A256GCMKW = "A256GCMKW";
240
241
// Content encryption algorithms
242
String A128CBC_HS256 = "A128CBC-HS256";
243
String A192CBC_HS384 = "A192CBC-HS384";
244
String A256CBC_HS512 = "A256CBC-HS512";
245
String A128GCM = "A128GCM";
246
String A192GCM = "A192GCM";
247
String A256GCM = "A256GCM";
248
249
// Compression algorithms
250
String DEF = "DEF";
251
}
252
253
/**
254
* JWE utilities for encryption and decryption operations
255
*/
256
public class JWEUtils {
257
/**
258
* Encrypt content using direct encryption with shared key
259
* @param content Content to encrypt
260
* @param encryptionAlg Content encryption algorithm
261
* @param encryptionKey Symmetric encryption key
262
* @return JWE token string
263
* @throws JWEException if encryption fails
264
*/
265
public static String encryptDirect(byte[] content, String encryptionAlg, SecretKey encryptionKey)
266
throws JWEException;
267
268
/**
269
* Decrypt JWE token using direct decryption with shared key
270
* @param jweString JWE token string
271
* @param encryptionKey Symmetric encryption key
272
* @return Decrypted content bytes
273
* @throws JWEException if decryption fails
274
*/
275
public static byte[] decryptDirect(String jweString, SecretKey encryptionKey)
276
throws JWEException;
277
278
/**
279
* Encrypt content using RSA key encryption
280
* @param content Content to encrypt
281
* @param keyAlg Key management algorithm
282
* @param encryptionAlg Content encryption algorithm
283
* @param publicKey RSA public key for key encryption
284
* @return JWE token string
285
* @throws JWEException if encryption fails
286
*/
287
public static String encryptRSA(byte[] content, String keyAlg, String encryptionAlg, PublicKey publicKey)
288
throws JWEException;
289
290
/**
291
* Decrypt JWE token using RSA key decryption
292
* @param jweString JWE token string
293
* @param privateKey RSA private key for key decryption
294
* @return Decrypted content bytes
295
* @throws JWEException if decryption fails
296
*/
297
public static byte[] decryptRSA(String jweString, PrivateKey privateKey)
298
throws JWEException;
299
}
300
```
301
302
### JWK (JSON Web Key)
303
304
JSON Web Key implementation for representing cryptographic keys in JSON format.
305
306
```java { .api }
307
/**
308
* JSON Web Key representation
309
*/
310
public class JWK {
311
/**
312
* Get the key type
313
* @return Key type (e.g., "RSA", "EC", "oct")
314
*/
315
public String getKeyType();
316
317
/**
318
* Get the key ID
319
* @return Key identifier
320
*/
321
public String getKeyId();
322
323
/**
324
* Get the algorithm
325
* @return Algorithm identifier
326
*/
327
public String getAlgorithm();
328
329
/**
330
* Get the key usage
331
* @return Key use (e.g., "sig", "enc")
332
*/
333
public String getKeyUse();
334
335
/**
336
* Get key operations
337
* @return List of key operations
338
*/
339
public List<String> getKeyOps();
340
341
/**
342
* Convert to PublicKey instance
343
* @return PublicKey object
344
*/
345
public PublicKey toPublicKey();
346
347
/**
348
* Check if key ID is present
349
* @return true if key has an ID
350
*/
351
public boolean hasKeyId();
352
353
/**
354
* Get custom JWK parameter
355
* @param name Parameter name
356
* @return Parameter value
357
*/
358
public Object getOtherKeyParameter(String name);
359
}
360
361
/**
362
* JSON Web Key Set representation
363
*/
364
public class JSONWebKeySet {
365
/**
366
* Get all keys in the set
367
* @return List of JWK objects
368
*/
369
public List<JWK> getKeys();
370
371
/**
372
* Get a key by its key ID
373
* @param kid Key identifier
374
* @return JWK object or null if not found
375
*/
376
public JWK getKeyByKid(String kid);
377
378
/**
379
* Get keys by algorithm
380
* @param algorithm Algorithm identifier
381
* @return List of matching JWK objects
382
*/
383
public List<JWK> getKeysByAlg(String algorithm);
384
385
/**
386
* Get keys by key use
387
* @param use Key use identifier
388
* @return List of matching JWK objects
389
*/
390
public List<JWK> getKeysByUse(String use);
391
}
392
393
/**
394
* RSA public key JWK representation
395
*/
396
public class RSAPublicJWK extends JWK {
397
/**
398
* Get the RSA modulus (n parameter)
399
* @return Base64URL encoded modulus
400
*/
401
public String getModulus();
402
403
/**
404
* Get the RSA public exponent (e parameter)
405
* @return Base64URL encoded exponent
406
*/
407
public String getPublicExponent();
408
409
/**
410
* Convert to RSA PublicKey
411
* @return RSAPublicKey instance
412
*/
413
public RSAPublicKey toRSAPublicKey();
414
}
415
416
/**
417
* Elliptic Curve public key JWK representation
418
*/
419
public class ECPublicJWK extends JWK {
420
/**
421
* Get the curve name (crv parameter)
422
* @return Curve identifier (e.g., "P-256", "P-384", "P-521")
423
*/
424
public String getCrv();
425
426
/**
427
* Get the x coordinate (x parameter)
428
* @return Base64URL encoded x coordinate
429
*/
430
public String getX();
431
432
/**
433
* Get the y coordinate (y parameter)
434
* @return Base64URL encoded y coordinate
435
*/
436
public String getY();
437
438
/**
439
* Convert to EC PublicKey
440
* @return ECPublicKey instance
441
*/
442
public ECPublicKey toECPublicKey();
443
}
444
445
/**
446
* Octet Key Pair (EdDSA) JWK representation
447
*/
448
public class OKPPublicJWK extends JWK {
449
/**
450
* Get the curve name (crv parameter)
451
* @return Curve identifier (e.g., "Ed25519", "Ed448")
452
*/
453
public String getCrv();
454
455
/**
456
* Get the public key value (x parameter)
457
* @return Base64URL encoded public key
458
*/
459
public String getX();
460
}
461
```
462
463
### JWK Builder and Utilities
464
465
```java { .api }
466
/**
467
* JWK builder for creating JWK objects from keys
468
*/
469
public class JWKBuilder {
470
/**
471
* Create JWK from RSA public key
472
* @param publicKey RSA public key
473
* @return RSAPublicJWK instance
474
*/
475
public static RSAPublicJWK createRSAJWK(RSAPublicKey publicKey);
476
477
/**
478
* Create JWK from EC public key
479
* @param publicKey EC public key
480
* @return ECPublicJWK instance
481
*/
482
public static ECPublicJWK createECJWK(ECPublicKey publicKey);
483
484
/**
485
* Create JWK from secret key
486
* @param secretKey Symmetric secret key
487
* @return JWK instance
488
*/
489
public static JWK createSecretJWK(SecretKey secretKey);
490
}
491
492
/**
493
* JWK parsing utilities
494
*/
495
public class JWKParser {
496
/**
497
* Parse JWK from JSON string
498
* @param json JWK JSON representation
499
* @return JWK instance
500
* @throws IOException if parsing fails
501
*/
502
public static JWK parseJWK(String json) throws IOException;
503
504
/**
505
* Parse JWK Set from JSON string
506
* @param json JWK Set JSON representation
507
* @return JSONWebKeySet instance
508
* @throws IOException if parsing fails
509
*/
510
public static JSONWebKeySet parseJWKSet(String json) throws IOException;
511
}
512
513
/**
514
* JWK utilities for key operations
515
*/
516
public class JWKUtil {
517
/**
518
* Convert JWK to KeyWrapper
519
* @param jwk JWK instance
520
* @return KeyWrapper instance
521
*/
522
public static KeyWrapper toKeyWrapper(JWK jwk);
523
524
/**
525
* Convert KeyWrapper to JWK
526
* @param keyWrapper KeyWrapper instance
527
* @return JWK instance
528
*/
529
public static JWK fromKeyWrapper(KeyWrapper keyWrapper);
530
531
/**
532
* Validate JWK structure and parameters
533
* @param jwk JWK to validate
534
* @return true if valid
535
*/
536
public static boolean isValid(JWK jwk);
537
}
538
```
539
540
### JOSE Parser and Base Classes
541
542
```java { .api }
543
/**
544
* Generic JOSE parser for JWS and JWE tokens
545
*/
546
public class JOSEParser {
547
/**
548
* Parse JOSE token (JWS or JWE)
549
* @param token JOSE token string
550
* @return JOSE object
551
* @throws JOSEException if parsing fails
552
*/
553
public static JOSE parse(String token) throws JOSEException;
554
555
/**
556
* Parse JOSE header only
557
* @param token JOSE token string
558
* @return JOSEHeader object
559
* @throws JOSEException if parsing fails
560
*/
561
public static JOSEHeader parseHeader(String token) throws JOSEException;
562
563
/**
564
* Check if token is JWS format
565
* @param token Token string
566
* @return true if JWS format
567
*/
568
public static boolean isJWS(String token);
569
570
/**
571
* Check if token is JWE format
572
* @param token Token string
573
* @return true if JWE format
574
*/
575
public static boolean isJWE(String token);
576
}
577
578
/**
579
* Base JOSE header representation
580
*/
581
public class JOSEHeader {
582
/**
583
* Get the algorithm header parameter
584
* @return Algorithm identifier
585
*/
586
public String getAlgorithm();
587
588
/**
589
* Get the type header parameter
590
* @return Type value
591
*/
592
public String getType();
593
594
/**
595
* Get the key ID header parameter
596
* @return Key identifier
597
*/
598
public String getKeyId();
599
600
/**
601
* Get the content type header parameter
602
* @return Content type value
603
*/
604
public String getContentType();
605
606
/**
607
* Get custom header parameter
608
* @param name Parameter name
609
* @return Parameter value
610
*/
611
public Object getHeaderParameter(String name);
612
}
613
614
/**
615
* Base JOSE token representation
616
*/
617
public class JOSE {
618
/**
619
* Get the JOSE header
620
* @return JOSEHeader object
621
*/
622
public JOSEHeader getHeader();
623
624
/**
625
* Get the raw token string
626
* @return Original token string
627
*/
628
public String serialize();
629
}
630
```
631
632
## Exception Handling
633
634
```java { .api }
635
/**
636
* Exception thrown during JWS input parsing
637
*/
638
public class JWSInputException extends Exception {
639
public JWSInputException(String message);
640
public JWSInputException(String message, Throwable cause);
641
}
642
643
/**
644
* Exception thrown during JWE operations
645
*/
646
public class JWEException extends Exception {
647
public JWEException(String message);
648
public JWEException(String message, Throwable cause);
649
}
650
651
/**
652
* General JOSE exception
653
*/
654
public class JOSEException extends Exception {
655
public JOSEException(String message);
656
public JOSEException(String message, Throwable cause);
657
}
658
```
659
660
## Usage Examples
661
662
```java
663
import org.keycloak.jose.jws.*;
664
import org.keycloak.jose.jwk.*;
665
import org.keycloak.jose.jwe.*;
666
import org.keycloak.crypto.*;
667
668
// Create and sign a JWS token
669
JWSBuilder builder = new JWSBuilder();
670
String jws = builder
671
.jsonContent(Map.of("sub", "user123", "name", "John Doe"))
672
.type("JWT")
673
.kid("key-1")
674
.sign(signerContext);
675
676
// Parse and verify JWS token
677
JWSInput jwsInput = new JWSInput(jws);
678
JWSHeader header = jwsInput.getHeader();
679
Map<String, Object> payload = jwsInput.readJsonContent(Map.class);
680
681
// Work with JWK Set
682
String jwksJson = "{ \"keys\": [...] }";
683
JSONWebKeySet jwks = JWKParser.parseJWKSet(jwksJson);
684
JWK signingKey = jwks.getKeyByKid("key-1");
685
PublicKey publicKey = signingKey.toPublicKey();
686
687
// JWE encryption/decryption
688
byte[] content = "sensitive data".getBytes();
689
String jweToken = JWEUtils.encryptDirect(content, JWEConstants.A256GCM, secretKey);
690
byte[] decrypted = JWEUtils.decryptDirect(jweToken, secretKey);
691
```