# auth0/java-jwt: JWT Signing and Verification for Server-Side Java

> A JWT library for server-side JVM applications, with a builder for creating tokens and a reusable verifier for checking them. It supports HMAC, RSA, RSA-PSS and ECDSA, and it deliberately leaves the JWT itself as an opaque string that your application passes around.

**auth0/java-jwt** — Java implementation of JSON Web Token (JWT)

- Repository: https://github.com/auth0/java-jwt
- Stars: 6,233 · Forks: 946
- Language: Java
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/auth0-java-jwt

## What auth0/java-jwt actually does for a Java service

A JWT is a signed string that carries claims. Someone has to produce that string on one side and check it on the other. auth0/java-jwt is the piece that does both inside a JVM process. The README describes it as a Java implementation of JSON Web Token (JWT) - RFC 7519, and it is explicit that the library is intended for server-side JVM applications.

That server-side framing matters more than it sounds. The library gives you two objects: JWT, which builds and signs tokens, and JWTVerifier, which checks them. It does not manage sessions, does not fetch keys from a JWKS endpoint, does not cache anything, and does not decide what a claim means. Those are your application's problems. What you get is a correct implementation of the signing and verification arithmetic for a fixed set of algorithms, plus claim validation hooks.

The intended audience is a backend engineer who already has an identity provider, a key pair or a shared secret, and a need to mint or check tokens at a service boundary. If you are looking for a framework that wires authentication into HTTP endpoints, this is not that. If you are looking for the primitive underneath such a framework, this is exactly that.

## The mechanism: builder for creation, reusable verifier for checks

Creation is a fluent builder. You call JWT.create(), set claims such as withIssuer, then call sign(algorithm). The algorithm object comes from the Algorithm factory, for example Algorithm.RSA256(rsaPublicKey, rsaPrivateKey). If the signing configuration is wrong or claims cannot be converted, the README states that a JWTCreationException is thrown.

Verification is a separate object with a separate lifecycle. You build a JWTVerifier through JWT.require(algorithm), add the claim requirements you care about, and call build(). The README calls the result a reusable verifier instance, which is the important design detail: the verifier is meant to be constructed once and reused, not rebuilt per request. Then verifier.verify(token) returns a DecodedJWT, and any invalid signature or unmet claim requirement surfaces as a JWTVerificationException.

So the data flow is: your application holds a key or secret, constructs an Algorithm, either signs a builder or configures a verifier, and passes plain strings across the boundary. The library never sees your HTTP layer. That separation is why it composes with Spring Boot or any other framework, and also why it will not help you if what you actually wanted was a filter that rejects unauthenticated requests.

The supported algorithms are HMAC (HS256, HS384, HS512), RSASSA-PKCS1-v1_5 (RS256, RS384, RS512), RSASSA-PSS (PS256, PS384, PS512) and ECDSA (ES256, ES384, ES512). ES256K is not in that list, and the README explains why: support for ECDSA with curve secp256k1 and SHA-256 was dropped because it has been disabled in Java 15.

## Installing auth0/java-jwt and signing your first token

The README gives two installation paths. Maven users add a dependency block; Gradle users add a single implementation line. The current version in the README is 4.6.1, which matches the most recent release listed for the project.

Maven:

```xml
<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>4.6.1</version>
</dependency>
```

Gradle:

```gradle
implementation 'com.auth0:java-jwt:4.6.1'
```

After the dependency resolves, the README's first example creates and signs a token with RS256. It wraps the call in a try block because signing can fail:

```java
try {
    Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, rsaPrivateKey);
    String token = JWT.create()
        .withIssuer("auth0")
        .sign(algorithm);
} catch (JWTCreationException exception){
    // Invalid Signing configuration / Couldn't convert Claims.
}
```

The variable token is the JWT string. Nothing else happens: no network call, no storage. Verification is the mirror image, and the README builds the verifier once and then verifies:

```java
Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, rsaPrivateKey);
JWTVerifier verifier = JWT.require(algorithm)
    .withIssuer("auth0")
    .build();

decodedJWT = verifier.verify(token);
```

If the signature is invalid or the issuer claim does not match, verify throws JWTVerificationException. The README points to EXAMPLES.md and the JavaDocs for scenarios beyond this one, so treat the snippet above as the starting point rather than the complete surface.

## Where auth0/java-jwt is the wrong tool

The README rules out one case directly: Android applications should use JWTDecode.Android instead. If your token handling lives in a mobile client, stop here.

Java version support is the second boundary. The library is supported for Java LTS versions 8, 11, 17 and 21. For non-LTS versions above 8, the README says consideration is given on a case-by-case basis, which is a polite way of saying you are outside the supported matrix. That is a real constraint if your build targets an interim release.

Algorithm support has a version dependency that is easy to miss. The README states that the RSASSA-PSS algorithms (PS256, PS384, PS512) rely on the JVM for RSASSA-PSS support, which is available natively from Java 11 onwards via the SunRsaSign provider. On Java 8 you must register a security provider that implements RSASSA-PSS, such as BouncyCastle, on the classpath, and the library bundles no additional provider. So PS256 on Java 8 is not a library configuration problem; it is a classpath problem you have to solve yourself.

There is also a security caveat the README raises rather than hides. It warns that the JVM has a critical vulnerability for ECDSA algorithms, CVE-2022-21449, and asks readers to review the details and update their environment. That is a JVM-level issue, not a flaw in this library, but it means choosing ES256, ES384 or ES512 without patching your runtime is not a decision the library can protect you from.

## How auth0/java-jwt differs from Nimbus and jjwt

The two libraries this project is most often weighed against are Nimbus JOSE+JWT and jjwt, and the difference is mostly about scope and how much of the JOSE stack you want in your dependency tree.

auth0/java-jwt is narrow by design. It handles JWS signing and verification for the algorithm list above, exposes a builder and a verifier, and stops. If you need JWE (encrypted tokens), JWK set parsing and rotation from a remote endpoint, or the broader JOSE object model, that work is not in this library's documented surface, and you would be adding it yourself or picking a library that ships it.

Nimbus JOSE+JWT covers a wider slice of the JOSE specifications, which makes it larger and more general. If your requirements include encrypted tokens or key-set handling, the broader library is the more direct fit, and adopting the narrow one first can mean a second migration later.

jjwt is the other common comparison. Both are Java JWT libraries with builder-style APIs, so the choice usually comes down to which algorithm set, Java version matrix and API shape your team already knows. The README does not compare itself to either project, so this is a judgement about scope, not a claim about correctness. What is verifiable here is the algorithm table, the supported Java LTS versions, the Java 8 caveat for RSASSA-PSS, and the absence of ES256K.

## Maintenance, releases and the key rotation notice

The repository is not archived, and the last push was on 2026-09-21, one day before this writing. Releases are frequent enough to be worth tracking: 4.6.1 on 2026-09-08, 4.6.0 on 2026-07-13, and 4.5.2 on 2026-04-29. A MIGRATION_GUIDE.md sits at the top level alongside CHANGELOG.md, which tells you the maintainers expect breaking changes to be documented rather than discovered.

The upgrade cost has one unusual wrinkle. The README carries a note stating that the signing keys used to sign previous releases of the SDK were rotated, that new patch builds were released using the new signing key, and that developers should upgrade. The note also says that if you have implemented a dependency signature validation step in your build process, you may see a warning that past releases cannot be verified, and that this is expected. For most teams this changes nothing. For teams that pin artifacts and validate signatures, it is a concrete reason to move to a current patch release rather than stay on an older one.

On licensing: the project is MIT licensed, and the README repeats that with a pointer to the LICENSE file. MIT is permissive, which in practice means you can use the library in closed-source products. That is a description of the licence text, not legal advice; if your organisation has an approval process for third-party dependencies, this is the kind of thing that process exists to check.

## Conclusion

Adopt auth0/java-jwt when you need to sign or verify JWTs inside a server-side JVM application and you want the token treated as an opaque string. Do not adopt it for Android client-side decoding (the README points to JWTDecode.Android) or for a non-LTS Java version above 8 without expecting case-by-case support. Before committing, verify the algorithm list against your identity provider, confirm your Java version supports RSASSA-PSS if you plan to use PS256, PS384 or PS512, and check whether your build performs dependency signature validation, because the README states that signing keys used for past releases were rotated and older releases will warn.

## FAQ

### What is a JWT in Java?

A JWT is a signed string carrying claims, defined by RFC 7519. auth0/java-jwt is a Java implementation of that specification for server-side JVM applications, giving you a builder to create tokens and a verifier to check them.

### How to generate a JWT in Java?

Call JWT.create(), set your claims such as withIssuer, and call sign(algorithm) with an Algorithm instance. The README's example uses Algorithm.RSA256(rsaPublicKey, rsaPrivateKey) and catches JWTCreationException if the signing configuration is invalid or claims cannot be converted.

### What are some good Java JWT libraries?

auth0/java-jwt is one option: a Java implementation of RFC 7519 for server-side JVM applications, supporting HMAC, RSASSA-PKCS1-v1_5, RSASSA-PSS and ECDSA. The README does not rank other libraries, but the article compares its scope with Nimbus JOSE+JWT and jjwt.

### What is java jwt?

It is the subject of this article: auth0/java-jwt, a Java implementation of JSON Web Token (JWT) per RFC 7519, intended for server-side JVM applications. It provides a builder for creating tokens and a verifier for checking them.

### java jwt vs jjwt?

Both are Java JWT libraries with builder-style APIs, and the README does not compare itself to jjwt. The verifiable differences are in scope and version matrix: auth0/java-jwt documents a fixed algorithm list, support for Java LTS 8, 11, 17 and 21, and no ES256K support since it was disabled in Java 15.

### java-jwt vs nimbus-jose-jwt?

auth0/java-jwt is narrow by design: it handles JWS signing and verification for its documented algorithm list and exposes a builder plus a verifier. Nimbus JOSE+JWT covers a wider slice of the JOSE specifications, so if you need encrypted tokens or key-set handling, the broader library is the more direct fit.

## Sources

- [auth0/java-jwt on GitHub](https://github.com/auth0/java-jwt)
- [Issues](https://github.com/auth0/java-jwt/issues)
- [License: MIT](https://github.com/auth0/java-jwt/blob/master/LICENSE)
- [README](https://github.com/auth0/java-jwt/blob/master/README.md)
- [Releases](https://github.com/auth0/java-jwt/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/auth0-java-jwt
