Asymmetric JWT (RS256) + Key Rotation (Rust)
Topics: RSA, RS256, JWT, JWKS, key rotation, asymmetric crypto
Problem
The HS256 world uses a shared secret — anyone who can verify can also forge. Here you sign with
an RSA private key (RS256) and verify with the public key, so verifiers authenticate tokens
without holding signing power. Then support key rotation via a kid-keyed key set (a minimal
JWKS), the way a gateway rotates signing keys without downtime.
pub struct Claims { pub sub: String, pub exp: i64 }
pub enum JwtError { Malformed, UnknownKey, InvalidSignature, Expired }
pub fn sign(claims: &Claims, kid: &str, priv_key: &RsaPrivateKey) -> Result<String, JwtError>;
pub struct KeySet { /* … */ }
impl KeySet {
pub fn new() -> Self;
pub fn add(&self, kid: &str, pub_key: RsaPublicKey);
pub fn remove(&self, kid: &str);
pub fn verify(&self, token: &str) -> Result<Claims, JwtError>;
}
sign produces a compact RS256 JWT (base64url(header).base64url(payload).base64url(sig)) with
kid in the header.
KeySet is a kid -> RsaPublicKey map (minimal JWKS) with add / remove.
verify reads the token's kid, selects the matching public key, verifies the RSA signature,
and checks exp (treat exp == 0 as "no expiry").
- Errors:
Malformed, UnknownKey, InvalidSignature, Expired.
Key concepts
- Asymmetric signing: the holder of the private key signs; anyone with the public key
verifies but cannot forge — why real identity providers publish a JWKS of public keys.
kid header: the key id tells the verifier which public key to use, so multiple keys are
valid at once — the basis for zero-downtime rotation (add new key → sign with it → remove the old
once its tokens expire).
- RS256 internals: sign =
RSASSA-PKCS1-v1_5(SHA256(header.payload)); here that's the rsa
crate's Pkcs1v15Sign::new::<Sha256>() over the SHA-256 digest, base64url-encoded as segment 3 —
no JWT library, just the crypto primitives.
Grading
Your solution.rs is the crate library; it's compiled with the dependencies in Cargo.toml and run
against the trusted tests.rs via cargo test. Only solution.rs is yours to edit.
Sign in to submit your solution.