KO

EN

Jwt-Hack: Reborn in Rust

Back in October 2020, I created a tool called jwt-hack to make security testing for JSON Web Tokens (JWTs) a bit more convenient. At the time, this Go-based tool was a project born out of my own necessity, focusing on its core crack feature to find JWT signing secrets using wordlists or brute force.

Truth be told, for the nearly five years since, the project has been somewhat neglected compared to my other work. While I made small improvements here and there, a part of me always felt it deserved more. That's why I finally decided to take the plunge and give the project a complete reboot, leading to the release of a new major version: jwt-hack v2.

In this post, I'd like to briefly share what the key changes in jwt-hack v2 are and where the project is headed next.

From Go to Rust: The Core Change

The biggest change in v2 is the complete switch from Go to Rust. Rewriting all the existing Go code in Rust took a fair amount of effort, but I believe it was a worthwhile endeavor.

The primary reason was stability. Frankly, v1 would occasionally run into unexpected memory-related issues. Thanks to Rust's Ownership system and its strict compile-time checks, I was able to prevent these kinds of bugs at the source, resulting in a much more stable tool.

Of course, a performance boost came along as a bonus. Even a simple benchmark shows a pretty satisfying speed improvement.

Metricjwt-hack v1jwt-hack v2
Time (mean ± σ)1.874 s ± 0.033 s678.6 ms ± 165.8 ms
Range (min … max)1.834 s … 1.935 s623.5 ms … 1150.4 ms
User Time7.312 s3516.7 ms
System Time1.985 s491.1 ms
Runs1010

Performance comparison of the crack feature under identical conditions ($ jwt-hack crack eyJ0e... --mode brute --max 4)

Strengthening the Foundation

This wasn't just about changing the language; I also focused on strengthening the project's foundation.

Test Coverage

One of the areas I paid the most attention to during v2's development was the test code. I wrote far more thorough tests compared to the previous version, creating a solid base to minimize side effects from future code changes and maintain stability as new features are added.

Codecov result

Compatibility

Even though it's a major version release, all the command-line options and usage patterns from v1 are fully inherited. This means you can update and apply it to your existing scripts or pipelines without any migration work.

Expanded Features

Building on the stability and development convenience gained from the switch to Rust, I've added several features that I'd long felt were necessary.

Support for More Algorithms

While it previously focused on HMAC-based algorithms (HS256, HS384, HS512), jwt-hack now supports asymmetric encryption algorithms like RSA (RS*) and ECDSA (ES*).

New Key-Based Functionality

Going beyond simple secret-based testing, it's now possible to generate, verify, and test tokens using private/public keys. For example, you can easily create a JWT signed with a private key like this:

ssh-keygen -t rsa -b 4096 -E SHA256 -m PEM -P "" -f RS256.key
jwt-hack encode '{"a":"z"}' --private-key RS256.key --algorithm=RS256

Make JWT with Private key

New Verify Mode

Truth be told, the previous version lacked even the basic functionality to verify if a JWT's signature was valid. This update introduces a verify mode that allows you to check a token's signature with a secret or a public key, making the tool more complete for token testing.

Broader Attack Vector Support

One of jwt-hack's core features is generating tokens for known attack vectors. In addition to the existing none algorithm and jku/x5u attacks, it now supports a wider range of vectors and will continue to expand in the future:

  • Algorithm Confusion (tampering with the alg header to HS256)
  • SQL Injection in kid (inserting an SQLi payload into the kid header)
  • Other known attack techniques

Installation

Cargo

If you're a Rust developer, you can install it directly via cargo.

cargo install jwt-hack

Homebrew

And for one of the most exciting pieces of news: jwt-hack is now included in the official homebrew-core! You can install and update it with a simple command, no need to tap a separate repository.

brew install jwt-hack

More

You can also get jwt-hack through various other channels, including the Snapcraft Package, Docker Hub, and GHCR.

Final Thoughts

Breathing new life into a long-neglected project was more enjoyable than I expected. It was great to see the tool improve, but what made it particularly fun was the process of getting to know the Rust language more deeply.

Going forward, I plan to build jwt-hack into a comprehensive tool packed with various features for JWT security testing. If you have any ideas for necessary features or improvements, please don't hesitate to leave a comment on the GitHub Issues. Your interest is the driving force behind this project.