Skip to content
ecdsa.com

JWK thumbprint · Rust

How to compute a JWK thumbprint (RFC 7638) in Rust

In Rust, the jsonwebtoken crate's Jwk::thumbprint computes the RFC 7638 thumbprint for EC, RSA and Ed25519 JWKs, and Jwk::from_decoding_key builds a JWK from a PEM key first. The run reproduces the published RFC 7638 and RFC 8037 thumbprints from JWK files and from PEM keys.

Tested with jsonwebtoken 11.1.0 (Rust 1.99.1, feature rust_crypto).

Cargo.toml — jsonwebtoken and serde_json
[dependencies]
jsonwebtoken = { version = "=11.1.0", features = ["rust_crypto"] }
serde_json = "=1.0.154"
src/main.rs — thumbprints from JWK files and from PEM keys
use jsonwebtoken::jwk::{Jwk, ThumbprintHash};
use jsonwebtoken::DecodingKey;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// From a JWK: Jwk::thumbprint implements RFC 7638 (kid, use and alg are ignored)
for file in ["ec.jwk.json", "rsa.jwk.json", "okp.jwk.json"] {
let jwk: Jwk = serde_json::from_str(&std::fs::read_to_string(file)?)?;
println!("{file}: {}", jwk.thumbprint(ThumbprintHash::SHA256)?);
}
// From a PEM public key: DecodingKey -> Jwk -> thumbprint
let pems: [(&str, fn(&[u8]) -> jsonwebtoken::errors::Result<DecodingKey>); 3] = [
("ec.pub.pem", DecodingKey::from_ec_pem),
("rsa.pub.pem", DecodingKey::from_rsa_pem),
("okp.pub.pem", DecodingKey::from_ed_pem),
];
for (file, parse) in pems {
let jwk = Jwk::from_decoding_key(&parse(&std::fs::read(file)?)?, None)?;
println!("{file}: {}", jwk.thumbprint(ThumbprintHash::SHA256)?);
}
Ok(())
}

How it works

  1. serde_json::from_str::<Jwk> parses a JWK; kid, use and alg land in common and are ignored by the thumbprint.
  2. jwk.thumbprint(ThumbprintHash::SHA256) returns the base64url thumbprint as a String.
  3. DecodingKey::from_ec_pem, from_rsa_pem and from_ed_pem read PEM public keys; Jwk::from_decoding_key(&key, None) turns them into JWKs.
  4. ThumbprintHash::SHA384 and SHA512 give the other hash variants.

Gotchas

  • from_decoding_key needs a crypto backend feature (rust_crypto or aws_lc_rs) to extract the key components from DER; without one, the program compiles and then panics inside jsonwebtoken's crypto module.
  • Each PEM constructor accepts only its key type: from_ec_pem on an RSA key is an error, so the code needs to know (or try) the type.
  • For keys outside jsonwebtoken's supported set — X25519, Ed448, secp256k1 — thumbprint returns an error; compute those over the RFC 7638 members with sha2 and base64 directly.
  • Thumbprints are of public keys: build the JWK from the DecodingKey, not from the EncodingKey, so the private part can never end up in it.

Related recipes