Welcome to jose.4.j!
The jose.4.j library is an open source (Apache 2.0) implementation of JWT and the JOSE specification suite. It is written in Java and relies solely on the JCA APIs for cryptography.
JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. JWT is the identity token format in OpenID Connect and it is also widely used in OAuth 2.0 and many other contexts that require compact message security.
The JWT code examples page shows how to easily produce and consume JWTs using this library.
The library supports the JWS/JWE compact serializations with the complete suite of JOSE algorithms. A more detailed breakdown is available below in the Algorithm Support section.
Getting the Library
The jose4j library is available in the Maven Central Repository. To use it in your project, add the following dependency to the <dependencies> section of your pom:
<dependency> <groupId>org.bitbucket.b_c</groupId> <artifactId>jose4j</artifactId> <version>0.9.3</version> </dependency>
jose.4.j is very easy to use and, to help get started, some code examples are provided demonstrating common things you might want to do with it.
Hello World JWE Example
The following snippet uses JWE to both encrypt and decrypt the message "Hello World!" in just a few lines of code.
Key key = new AesKey(ByteUtil.randomBytes(16)); JsonWebEncryption jwe = new JsonWebEncryption(); jwe.setPayload("Hello World!"); jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A128KW); jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256); jwe.setKey(key); String serializedJwe = jwe.getCompactSerialization(); System.out.println("Serialized Encrypted JWE: " + serializedJwe); jwe = new JsonWebEncryption(); jwe.setAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.PERMIT, KeyManagementAlgorithmIdentifiers.A128KW)); jwe.setContentEncryptionAlgorithmConstraints(new AlgorithmConstraints(ConstraintType.PERMIT, ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256)); jwe.setKey(key); jwe.setCompactSerialization(serializedJwe); System.out.println("Payload: " + jwe.getPayload());
Additional and more detailed examples and explanations are available:
- JWT Examples shows how to produce and consume JSON Web Tokens (including using Ed25519 EdDSA and X25519 ECDH).
- JWS Examples shows how to easily apply and verify signatures including how to use the "b64" RFC 7797 JWS Unencoded Payload Option
- JWE Examples shows how to encrypt and decrypt messages.
- A very simple Android project showing how to use jose4j with Android keystore system keys requiring user biometric authentication for use
- A presentation at IIW 18 and a similar one at CIS 2014 have some code examples along with some general information about JOSE and JWT.
- Javadocs are online here at javadoc.io though they are currently a touch sparse on actual documentation (but getting better!)
- Response and analysis to some potential JWT vulnerabilities has some (maybe) useful info on using AlgorithmConstraints to specify what algorithms are allowed per JOSE or JWT object
The Release Notes give a changelog of the project.
All of the JOSE algorithms are fully implemented by jose4j. However, the library relies on the underlying cryptography provider in the Java Runtime Environment so, depending on the deployment environment, some algorithms may not be available at runtime. The tables below lists all the supported JWS/JWE/JWK algorithms and is annotated with some common JCA provider requirements.
|Digital Signature or MAC Algorithm||JWS "alg" Parameter Value|
|HMAC using SHA-2||HS256, HS384 and HS512|
|RSASSA-PKCS1-V1_5 Digital Signatures with with SHA-2||RS256, RS384 and RS512|
|Elliptic Curve Digital Signatures (ECDSA) with SHA-2||ES256, ES384, ES512 and ES256K§|
|RSASSA-PSS Digital Signatures with SHA-2||PS256†, PS384† and PS512†|
|Edwards-Curve Digital Signature Algorithm||EdDSA‡‡|
JWE Key Encryption and Key Agreement
|Key Management Algorithm||JWE "alg" Parameter Value|
|Direct encryption with a shared symmetric key||dir|
|RSAES-PKCS1-V1_5 key encryption||RSA1_5|
|RSAES using OAEP key encryption||RSA-OAEP and RSA-OAEP-256¶|
|AES key wrap||A128KW, A192KW* and A256KW*|
|AES GCM key encryption||A128GCMKW‡, A192GCMKW*‡ and A256GCMKW*‡|
|Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF||ECDH-ES|
|Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF with AES key wrap||ECDH-ES+A128KW, ECDH-ES+A192KW*, ECDH-ES+A256KW*|
|PBES2 with HMAC SHA-2 and AES key wrapping||PBES2-HS256+A128KW, PBES2-HS384+A192KW* and PBES2-HS512+A256KW*|
JWE Content Encryption
|Content Encryption Algorithm||JWE "enc" Parameter Value|
|Authenticated encryption with AES-CBC and HMAC-SHA2||A128CBC-HS256, A192CBC-HS384* and A256CBC-HS512*|
|Authenticated encryption with Advanced Encryption Standard (AES) in Galois/Counter Mode (GCM)||A128GCM‡, A192GCM*‡ and A256GCM*‡|
|Compression Algorithm||JWE "zip" Parameter Value|
|DEFLATE Compressed Data Format from RFC 1951||DEF|
|Key Type||JWK "kty" Parameter Value|
|Elliptic Curve Public/Private Keys||EC|
|RSA Public/Private Keys||RSA|
|Symmetric Keys (Octet sequence)||oct|
|Octet Key Pair (Ed25519/Ed448‡‡ & X25519/X448††)||OKP|
* Requires the JCE's Unlimited Strength Jurisdiction Policy Files be installed for the JRE (download for Java 7 and Java 8 and note that later versions have the unlimited cryptographic policy enabled by default).
† Requires Java 11, Java 8 Java 8u251, or the Bouncy Castle JCA provider (or another provider which supports RSASSA-PSS)
‡ Requires Java 8 or the Bouncy Castle v1.50+ JCA provider (or another provider which supports AEAD ciphers though the JCA interface including recognizing GCMParameterSpec)
¶ Requires Java 8 or the Bouncy Castle JCA provider (or another provider which supports RSA/ECB/OAEPWithSHA-256AndMGF1Padding and an OAEPParameterSpec that indicates SHA-256 for MGF1)
§ Requires a provider that supports the secp256k1 curve (prior to Java 16 or Bouncy Castle)
‡‡ Requires Java 17
†† Requires Java 11
Jose4j is compiled for Java 7 and will run on Java 8 and later versions.
I'd like to thank Dan McNulty, Dmitry Vsekhvalnov, Guoping Liu, Jason Musgrave, Jeremie Miller, John Bradley, Justin Kwong, Travis Spencer, Joseph Heenan, Thomas Broyer, Tim McLean, Jan Høydahl, Jan Willem Janssen, Magnus Andersson, Samo Remec, Axel Nennker, Yaroslav Soltys, Quan Nguyen, Sergey Beryozkin, Yang Yu, James Manger, Aaron Levin, Eivind Larsen, Bastien Jansen, Marcin Nowak, Thomas Zimmermann and Antonio Sanso for feedback and suggestions (please let me know if you deserve acknowledgment but I've somehow forgotten you).
Lastly, but maybe most importantly, I'd like to thank my employer, Ping Identity. I do believe that Ping benefits from this work (the library is used extensively in Ping's products). But I know for sure none of it would have happened without Ping.