Versions Compared

Key

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

...

Code Block
xml
xml
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-rs-security-jose-jaxrs</artifactId>
  <version>3.1.7</version>
</dependency>
 

JOSE Overview and Implementation

JOSE consists of the following key parts:

...

Typically one would supply an algorithm property in a type-safe way either to JWS or JWE processor, for example,  SignatureAlgorithm.HS256 (HMAC signature) for JWS, KeyAlgorithm.A256KW (key encryption wrap) plus ContentAlgorithm.A256GCM for JWE, etc. Each enum has methods for checking a key size, JWA and Java JCA algorithm names.

...

Support for the pluggable strategies for loading JWKs is on the map.

JWS Signature

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 a MAC key.

Here is one of the ways you can do it in CXF, where a Json Web Token (JWT, see one of the next sections) is signed by a MAC key:
 

Code Block
languagejava
titleCXF JWS HMac
// sign
JoseHeaders headers = new JoseHeaders();
headers.setAlgorithm(SignatureAlgorithm.HS256.getJwaName());

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);
assertTrue(jws.verifySignatureWith(new HmacJwsSignatureVerifier(ENCODED_MAC_KEY,
                                      SignatureAlgorithm.HS256)));
JwtToken token = jws.getJwtToken();
JoseHeaders headers = token.getHeaders();
assertEquals(SignatureAlgorithm.HS256.getJwaName(), headers.getAlgorithm());
validateClaims(token.getClaims());

 

CXF ships JWS related classes in this package and offers a support for all of JWA signature algorithms.

JwsSignatureProvider supports signing the content, JwsSignatureVerifier - validating the signatures. Providers and verifiers supporting RSA, HMac and Elliptic Curve signature algorithms are shipped.

JwsCompactConsumer and JwsCompactProducer offer a utility support for creating and validating JWS compact serialization and accept keys in a variety of formats

(as JWKs, JCA representations, created out of band and wrapped in either JwsSignatureProvider or JwsSignatureVerifier).

JwsJwtCompactConsumer and JwsJwtCompactProducer are JwsCompactConsumer and JwsCompactProducer specializations that offer a utility support for signing Json Web Tokens in a compact format.

JwsJsonConsumer and JwsJsonProducer support JWS JSON (full) serialization.

JwsOutputStream and JwsJsonOutputStream are specialized output streams that can be used in conjunction with JWS JAX-RS filters (see one of the next sections)

to support the best effort at streaming the content while signing it.  These classes will use JwsSignature  optionally returned from JwsSignatureProvider

instead of working with the consumer utility classes which deal with the signature process completely in memory.

 

...

Here are some code examples:

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

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

CXF ships JWS related classes in this package and offers a support for all of JWA signature algorithms.

Signature and Verification Providers

JwsSignatureProvider supports signing the content, JwsSignatureVerifier - validating the signatures. These providers can be initialized from the keys or certificates loaded from JWK or JCA stores.

Note the signature and verification capabilities are represented by 2 different interfaces - it was done to keep the interfaces minimalistic and have the concerns separated which can be appreciated most in the cases where the code only signs or only validates.

The following table shows the algorithms and the corresponding providers:

 JwsSignatureProviderJwsSignatureVerifier
HMAC
HmacJwsSignatureProvider
HmacJwsSignatureVerifier
RSASSA-PKCS1PrivateKeyJwsSignarureProviderPublicKeyJwsSignatureVerifier
ECDSAEcDsaJwsSignarureProviderEcDsaJwsSignatureVerifier
RSASSA-PSSPrivateKeyJwsSignarureProviderPublicKeyJwsSignatureVerifier
NoneNoneJwsSignarureProviderNoneJwsSignatureVerifier

Either of these providers (except for None) can be initialized with the keys loaded from JWK or JCA stores or from the in-memory representations.

JWS Compact

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.

JwsCompactProducer and JwsCompactConsumer offer a support for producing and consuming compact JWS sequences, protecting the data in JSON or non-JSON formats.

JwsJwtCompactProducer and JwsJwtCompactConsumer are their simple extensions which help with processing typed JWT Tokens.

 For example, here is how an Appendix A1 example can be done in CXF:

 

Code Block
languagejava
titleCXF JWS HMac
// Sign
// Algorithm properties are set in the headers
JoseHeaders headers = new JoseHeaders();
headers.setAlgorithm(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);
assertTrue(jws.verifySignatureWith(new HmacJwsSignatureVerifier(ENCODED_MAC_KEY,
                                      SignatureAlgorithm.HS256)));
JwtToken token = jws.getJwtToken();
JoseHeaders headers = token.getHeaders();
assertEquals(SignatureAlgorithm.HS256, headers.getAlgorithm());
validateClaims(token.getClaims());

JWS JSON

JWS with Clear Payload

JWE Encryption

JWE (JSON Web Encryption) document describes how a document content, and, when applicable, a content encryption key, can be encrypted. For example, Appendix A1 shows how the content can be encrypted

...