Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejs
titlePublic Jwk RSA Key
{
  "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
languagejava
titleJWK examples
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):

AlgorithmJWS AlgorithmJWS Header 'alg'JwsSignatureProviderJwsSignatureVerifier
HMACHS256, HS384, HS512

HmacJwsSignatureProvider

HmacJwsSignatureVerifier

RSASSA-PKCS1-v1_5RS256, RS384, RS512PrivateKeyJwsSignatureProviderPublicKeyJwsSignatureVerifier
ECDSAES256, ES384, ES512EcDsaJwsSignatureProviderEcDsaJwsSignatureVerifier
RSASSA-PSSPS256, PS384, PS512PrivateKeyJwsSignatureProviderPublicKeyJwsSignatureVerifier
NonenoneNoneJwsSignatureProviderNoneJwsSignatureVerifier

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
languagejava
titleCXF JWS Compact HMac
// 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
languagejava
titleCXF JWS Compact HMac
// 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
languagejava
titleCXF JWS JSON
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):

AlgorithmJWE Header 'alg'KeyEncryptionProviderKeyDecryptionProvider
RSAES-PKCS1-v1_5

RSA1_5

RSAKeyEncryptionAlgorithm

RSAKeyDecryptionAlgorithm

RSAES OAEP

RSA-OAEP,

RSA-OAEP-256

RSAKeyEncryptionAlgorithmRSAKeyDecryptionAlgorithm
AES Key Wrap

A128KW,

A192KW,

A256KW

AesKeyWrapEncryptionAlgorithmAesKeyWrapDecryptionAlgorithm
DirectdirDirectKeyEncryptionAlgorithmDirectKeyDecryptionAlgorithm
ECDH-ES Wrap

ECDH-ES+A128KW

(+A192KW,

+256KW)

EcdhAesWrapKeyEncryptionAlgorithmEcdhAesWrapKeyDecryptionAlgorithm
ECDH-ES Direct

ECDH-ES

EcdhDirectKeyJweEncryptionEcdhDirectKeyJweDecryption
AES-GCM

A128GCMKW,

A192GCMKW,

A256GCMKW

AesGcmWrapKeyEncryptionAlgorithmAesGcmWrapKeyDecryptionAlgorithm
PBES2

PBES2-HS256+A128KW

PBES2-HS384+A192KW

PBES2-HS512+A256KW

PbesHmacAesWrapKeyEncryptionAlgorithmPbesHmacAesWrapKeyDecryptionAlgorithm

...

AlgorithmJWE Header 'enc'ContentEncryptionProviderContentDecryptionProvider
AES_CBC_HMAC_SHA2

A128CBC-HS256(-HS384,

-HS512)

AesCbcHmacJweEncryption,

AesCbcHmacJweDecryption

AES-GCM

A128GCM,

A92GCM,

A256GCM

AesGcmContentEncryptionAlgorithmAesGcmContentDecryptionAlgorithm

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.

...