Nimbus JOSE + JWT 3.0, redesigned and with AES key wrap support
Thanks to Melisa Halsband, a contributor from CertiVox UK, the Nimbus library can now handle JSON Web Tokens (JWT) and other objects encrypted with a shared key using the AES or AES/GCM key wrap algorithm.
These are the JWA identifiers for the newly added algorithms:
- For AES key wrap encryption: A128KW, A192KW and A256KW
- For AES GCM key wrap encryption: A128CGMKW, A192CGMKW and A256CGMKW
Support of AES key wrap necessitated a number of braking changes to the JOSE header and object classes. That cleared the way for a number of other significant changes in the new 3.0 release, all of which we hope you’ll find useful :)
Simplified immutable headers
The plain / JWS / JWE header classes are now simplified and completely immutable, which makes for safer development. A builder is available to help you construct headers where you need to specify additional parameters than the mandatory alg and enc:
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256).
keyID("123").
contentType("text/plain").
customParam("exp", new Date().getTime()).
build();
To facilitate AES key wrap the JWE header was given direct support for the iv and tag parameter. We also added support for the new x4t#S256 (X.509 certificate SHA-256 thumbprint) header parameter added in draft 27 of the JOSE specs.
AES key wrap encryption
AES key wrap is useful in situations when you want to encrypt a message using a shared secret key, e.g. to ensure confidentiality of ID tokens in OpenID Connect where the client application has been issued with a simple client secret at registration.
Note that the key length must match the one required by the algorithm:
- 128 bit key for A128KW
- 192 bit key for A192KW
- 256 bit key for A256KW
// Create JWE object
JWEHeader header = new JWEHeader(JWEAlgorithm.A128KW, EncryptionMethod.A128CBC_HS256);
Payload payload = new Payload("Hello world!");
JWEObject jweObject = new JWEObject(header, payload);
// Encrypt with secret key
JWEEncrypter encrypter = new AESEncrypter(secretKey);
jweObject.encrypt(encrypter);
// Output JWE string
jweObject.serialize();
// ...
// Parse JWE string on recipient side
jweObject = JWEObject.parse(jweString);
// Decrypt with same secret key
JWEDecrypter decrypter = new AESDecrypter(key128);
jweObject.decrypt(decrypter);
// Get the decrypted payload
assertEquals("Hello world!", jweObject.getPayload().toString());
Encryption with AES GCM key wrap is similar, you just need to specify A128GCMKW as the JWE algorithm instead.
Serialising single-valued JWT audience (aud) claims
A developer complained that some JWT libraries cannot handle JWT audience (aud) values that are JSON arrays, even in the simple case (array with a single audience). To enable interop with such software we decided to modify the JWTClaimsSet class, so that single-valued aud claims are now output as a string.
JWT claims set with a single aud:
{
"iss": "https://c2id.com",
"sub": "alice",
"aud": "http://app.example.com"
}
JWT claims set with multiple aud values:
{
"iss": "https://c2id.com",
"sub": "alice",
"aud": [ "http://app1.example.com", "http://app2.example.com" ]
}
Java 7 is now the minimum requirement
With the new 3.0 release you will now need Java 7 to build and run the library. Java 6 is no longer officially supported as of February 2013, so we decided to drop support for it too, and start enjoying the language features Java 7 has to offer (and are already eyeing Java 8, but we’ll have to be patient ;)
Matching IETF specifications
From the JOSE WG:
From the OAuth WG:
Download
The Maven Dependency for the new 3.0 release:
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>3.0</version>
</dependency>
For other methods check out the downloads page.