...
Code Block | ||||
---|---|---|---|---|
| ||||
{ "kty":"RSA", "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx 4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2 QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e":"AQAB", "alg":"RS256", "kid":"Public RSA Key"} |
...
Support for the pluggable strategies for loading JWKs is on the map.
Here are some code examplesFor example, here is how you can load a JWK key using its 'kid':
Code Block | ||||
---|---|---|---|---|
| ||||
InputStream is = JsonWebKeyTest.class.getResourceAsStream(fileName); JsonWebKeys keySet = JwkUtils.readJwkSet(is); JsonWebKey key = keySet.getKey("Public RSA Key"); String thumbprint = JwkUtils.getThumbprint(key); assertEquals("NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", thumbprint); KeyType keyType = key.getKeyType(); assertEquals(KeyType.RSA, thumbprint); |
JWS Signature
JsonWebKeys also supports the retrieval of keys by their type (RSA, EC, Octet) and operation (ENCRYPT, SIGN, etc).
Once you have JWK loaded it is typically submitted to JWS or JWE providers.
JWS Signature
JWS (JSON Web Signature) document describes how a document content can be signed. JWS (JSON Web Signature) document describes how a document content can be signed. For example, Appendix A1 shows how the content can be signed with an HMAC key
...
The following table shows the algorithms and the corresponding providers :(org.apache.cxf.rs.security.jose.jws package):
Algorithm | JWS | Algorithm | JWS Header 'alg' | JwsSignatureProvider | JwsSignatureVerifier |
HMAC | HS256, HS384, HS512 | HmacJwsSignatureProvider | HmacJwsSignatureVerifier | ||
RSASSA-PKCS1-v1_5 | RS256, RS384, RS512 | PrivateKeyJwsSignatureProvider | PublicKeyJwsSignatureVerifier | ||
ECDSA | ES256, ES384, ES512 | EcDsaJwsSignatureProvider | EcDsaJwsSignatureVerifier | ||
RSASSA-PSS | PS256, PS384, PS512 | PrivateKeyJwsSignatureProvider | PublicKeyJwsSignatureVerifier | ||
None | none | NoneJwsSignatureProvider | NoneJwsSignatureVerifier |
Either of these providers (except for None) can be initialized with the keys loaded from JWK or JCA Java JKS stores or from the in-memory representations.
RS256/384/512 algorithms are likely to be used most often at the moment due to existing JKS stores being available everywhere and a relatively easy way of making the public validation keys available. 'None' algorithm might be useful when a JWS sequence is subsequently JWE-encrypted or when a 2-way TLS (with client and server certificates) is used.
JWS Compact
Once you have decided which algorithm needs to be supported you can initialize an appropriate pair of JwsSignatureProvider and JwsSignatureVerifier if both signing the data and the verification are needed. If only the signing is needed - select JwsSignatureProvider, only the verification - select JwsSignatureVerifier. The selected providers are submitted directly or indirectly to JWS Compact or JWS JSON producers or consumers.
JWS Compact
JWS Compact representation is the most often used JOSE sequence. It is the concatenation of Base64URL-JWS Compact representation is the most often used JOSE sequence. It is the concatenation of Base64URL-encoded sequence if JWS headers (algorithm and other properties), Base64URL-encoded sequence of the actual data being protected and Base64URL-encoded sequence of the signature algorithm output bytes.
...
Code Block | ||||
---|---|---|---|---|
| ||||
// Sign // Algorithm properties are set in the headers JoseHeaders headers = new JoseHeaders(); headers.setAlgorithm. In this case JwsHeaders do not have to be directly created // (see the next example), JwsCompactProducer will initialize them if needed and set an alorithm by checking // JwsSignatureProvider. JwsHeaders need to be initialized directly if not only algorithm but other properties // set too JwsHeaders headers = new JwsHeaders(SignatureAlgorithm.HS256); // This is the actual data content, JWT in this case, but can be an arbitrary JSON or non-JSON data JwtClaims claims = new JwtClaims(); claims.setIssuer("joe"); claims.setExpiryTime(1300819380L); claims.setClaim("http://example.com/is_root", Boolean.TRUE); JwsCompactProducer jwsProducer = new JwsJwtCompactProducer(claims); // Load HmacJwsSignatureProvider directly, see the next example for the alternative approach String jwsSequence = jwsProducer.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY, SignatureAlgorithm.HS256)); // validate JwsJwtCompactConsumer jws = new JwsJwtCompactConsumer(jwsSequence); // Load HmacJwsSignatureVerifier directly, see the next example for the alternative approach assertTrue(jws.verifySignatureWith(new HmacJwsSignatureVerifier(ENCODED_MAC_KEY, SignatureAlgorithm.HS256))); // Get the data JwtClaims protectedClaims = jws.getJwtClaims(); |
In the above example, the data (JwtToken) is submitted to an instance of JwsCompactProducer (JwsJwtCompactProducer) and signed with an HMac key.
Here is another example:
Code Block | ||||
---|---|---|---|---|
| ||||
// Sign // Algorithm properties are set in the headers JwsHeaders headers = new JwsHeaders(SignatureAlgorithm.HS256); JwsCompactProducer jwsProducer = new JwsJwtCompactProducer(token); // Load HmacJwsSignatureProvider directly, see the next example for the alternative approach String jwsSequence = jwsProducer(SignatureAlgorithm.HS256); // This is the actual data content, JWT in this case, but can be an arbitrary JSON or non-JSON data JwtClaims claims = new JwtClaims(); claims.setIssuer("joe"); claims.setExpiryTime(1300819380L); claims.setClaim("http://example.com/is_root", Boolean.TRUE); JwtToken token = new JwtToken(headers, claims); JwsCompactProducer jws = new JwsJwtCompactProducer(token); jws.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY, SignatureAlgorithm.HS256)); assertEquals(ENCODED_TOKEN_SIGNED_BY_MAC, jws.getSignedEncodedJws()); // validate JwsJwtCompactConsumer jws = new JwsJwtCompactConsumer(ENCODED_TOKEN_SIGNED_BY_MAC); // validate JwsJwtCompactConsumer jws = new JwsJwtCompactConsumer(jwsSequence); // Load HmacJwsSignatureVerifier directly, see the next example for the alternative approach assertTrue(jws.verifySignatureWith(new HmacJwsSignatureVerifier(ENCODED_MAC_KEY, SignatureAlgorithm.HS256))); // Get the data JwtToken token = jws.getJwtToken(); JoseHeaders headers = token.getHeaders(); assertEquals(SignatureAlgorithm.HS256, headers.getAlgorithm()); validateClaims(token.getClaims()); |
In the above example, the data (JwtToken) is submitted to an instance of JwsCompactProducer (JwsJwtCompactProducer) and signed with an HMac key.
JWS JSON
While JWS Compact is optimized and represents a concatenation of up to 3 Base64URL values, JWS JSON is an open JSON container, see Appendix 6.
...
Code Block | ||||
---|---|---|---|---|
| ||||
JwsJsonProducer producer = new JwsJsonProducer(UNSIGNED_PLAIN_JSON_DOCUMENT); JwsHeaders headerEntries = new JwsHeaders(SignatureAlgorithm.HS256); producer.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY_1, SignatureAlgorithm.HS256), headerEntries); producer.signWith(new HmacJwsSignatureProvider(ENCODED_MAC_KEY_2, SignatureAlgorithm.HS256), headerEntries); assertEquals(DUAL_SIGNED_JWS_JSON_DOCUMENT, producer.getJwsJsonSignedDocument()); JwsJsonConsumer consumer = new JwsJsonConsumer(DUAL_SIGNED_DOCUMENT); JsonWebKeys jwks = readKeySet("jwkPublicJsonConsumerSet.txt"); List<JwsJsonSignatureEntry> sigEntries = consumer.getSignatureEntries(); assertEquals(2, sigEntries.size()); // 1st signature String firstKid = (String)sigEntries.get(0).getKeyId(); JsonWebKey rsaKeyfirstKey = jwks.getKey(firstKid); assertTrue(sigEntries.get(0).verifySignatureWith(rsaKeyfirstKey)); // 2nd signature String secondKid = (String)sigEntries.get(1).getKeyId(); JsonWebKey ecKeysecondKey = jwks.getKey(secondKid); assertTrue(sigEntries.get(1).verifySignatureWith(ecKeysecondKey)); |
JWS with Detached Content
...
The following table shows the key encryption algorithms and the corresponding prov,idersproviders (org.apache.cxf.rs.security.jose.jwe package):
Algorithm | JWE Header 'alg' | KeyEncryptionProvider | KeyDecryptionProvider |
RSAES-PKCS1-v1_5 | RSA1_5 | RSAKeyEncryptionAlgorithm | RSAKeyDecryptionAlgorithm |
RSAES OAEP | RSA-OAEP, RSA-OAEP-256 | RSAKeyEncryptionAlgorithm | RSAKeyDecryptionAlgorithm |
AES Key Wrap | A128KW, A192KW, A256KW | AesKeyWrapEncryptionAlgorithm | AesKeyWrapDecryptionAlgorithm |
Direct | dir | DirectKeyEncryptionAlgorithm | DirectKeyDecryptionAlgorithm |
ECDH-ES Wrap | ECDH-ES+A128KW (+A192KW, +256KW) | EcdhAesWrapKeyEncryptionAlgorithm | EcdhAesWrapKeyDecryptionAlgorithm |
ECDH-ES Direct | ECDH-ES | EcdhDirectKeyJweEncryption | EcdhDirectKeyJweDecryption |
AES-GCM | A128GCMKW, A192GCMKW, A256GCMKW | AesGcmWrapKeyEncryptionAlgorithm | AesGcmWrapKeyDecryptionAlgorithm |
PBES2 | PBES2-HS256+A128KW PBES2-HS384+A192KW PBES2-HS512+A256KW | PbesHmacAesWrapKeyEncryptionAlgorithm | PbesHmacAesWrapKeyDecryptionAlgorithm |
...
Algorithm | JWE Header 'enc' | ContentEncryptionProvider | ContentDecryptionProvider |
AES_CBC_HMAC_SHA2 | A128CBC-HS256(-HS384, -HS512) | AesCbcHmacJweEncryption, | AesCbcHmacJweDecryption |
AES-GCM | A128GCM, A92GCM, A256GCM | AesGcmContentEncryptionAlgorithm | AesGcmContentDecryptionAlgorithm |
All of the above providers can be initialized with the keys loaded from JWK or JCA Java JKS stores or from the in-memory representations.
...