HSM / PKCS#11 / Multi-Algorithm Signing
What you will do: Choose a JWT signing algorithm (RS256, ES256 or ML-DSA-44/65/87), Sign Token to see the header, unchanged payload and signature, then Verify Signature against the JWKS public key over PKCS#11.
Worked example: Switch from the default RS256 to ML-DSA-65: the signature grows from 256 to 3,309 bytes (12.9x vs RS256) in the Size Impact Analysis, and Verify Signature returns Signature valid — CKR_OK.
Runtime and privacy: The cryptographic exercise runs in this browser. Review the site privacy terms before entering sensitive material; use synthetic inputs for learning and evaluation.
Browse all Crypto Lab tools · Learn with Identity & Access Management with PQC
For your role
- Developer / Engineer
- Switch the signing algorithm from RS256 (RSA-2048) to an ML-DSA variant, press Sign Token (Live WASM) and then Verify Signature: the header, the signature size and the Size Impact Analysis show what your JWT libraries and token limits will see.
- Security Architect
- Use the Size Impact Analysis and the CBOR Token Encoding (CWT / COSE) alternative to decide whether a PQC token still fits your headers, cookies and gateways before choosing the algorithm.
- Researcher / Academic
- Run the IAM PQC Known Answer Tests panel, then compare the same payload signed with each algorithm to measure the exact signature and header overhead.
- IT Ops / DevOps
- The Verification Flow — Relying Party Perspective panel shows what every service that validates tokens must be able to parse after the switch; use it to list which relying parties need updating first.
Token Signing Migration Lab
Compare JWT signing algorithms side-by-side. Toggle between classical RS256/ES256 and quantum-safe ML-DSA variants to observe signature size impact and header changes.
Live HSM Mode Active
SoftHSM3 · PKCS#11 v3.2 · Rust · session open
Select algorithm to see header changes and signature size impact
{
"alg": "RS256",
"typ": "JWT",
"kid": "rsa-2048-key-001"
}alg field must match the signing key type. JWK Set endpoint must expose the corresponding PQC public key.{
"sub": "user-1234",
"name": "Alice Engineer",
"email": "alice@corp.example",
"roles": ["developer", "ci-pipeline"],
"iat": 1741392000,
"exp": 1741395600,
"iss": "https://auth.corp.example",
"aud": "https://api.corp.example"
}Size Impact Analysis
- • HTTP Authorization header limit (8KB default in Nginx): ML-DSA-87 tokens may require header size increase
- • Cookie size limit (4KB): Bearer tokens in cookies must use ML-DSA-44 or switch to short-lived opaque tokens
- • Load balancer JWT validation: Envoy, Kong, AWS ALB must update JWT algorithms allow-list to include ML-DSA variants
- • Client SDK updates: JOSE/JWT libraries (jose, jsonwebtoken, PyJWT) need PQC algorithm support — check vendor roadmaps
Alternative: CBOR Token Encoding (CWT / COSE)
JWT uses text-based JSON encoding. For constrained environments (IoT, mobile credentials, embedded systems), CBOR Web Tokens (CWT) with COSE signatures offer a binary-encoded alternative that reduces overhead — important when ML-DSA signatures already add kilobytes.
- • Text (base64url JSON)
- • Wide browser/library support
- • RFC 9964 (ML-DSA for JOSE and COSE)
- • Published May 2026
- • Binary (CBOR-encoded)
- • Smaller envelope overhead
- • RFC 9964 (ML-DSA for JOSE and COSE)
- • Used in ISO 18013-5 mDL
- • IoT / embedded: CWT/COSE
- • Mobile credentials: CWT/COSE
- • Enterprise SSO / web: JWT
- • Both: same ML-DSA signature
Both JWT and CWT use the same underlying ML-DSA (FIPS 204) signature — only the token envelope encoding differs. See RFC 9964 and RFC 9052 in the Library for specification details.
Verification Flow — Relying Party Perspective
After the IdP signs a JWT, the relying party must verify it. The verification chain: fetch JWKS endpoint → match kid → verify signature with the public key. With Live WASM enabled, click Verify to execute a real PKCS#11 v3.2 verification against the signed token above.
{
"keys": [{
"kty": "RSA",
"alg": "RS256",
"kid": "rsa-2048-key-001",
"n": "sLjA...long modulus...",
"e": "AQAB",
"use": "sig"
}]
}GET /.well-known/jwks.json — resolve public key matching kid in JWT header
base64url(header) + "." + base64url(payload) — identical to what was signed
PKCS#11 v3.2 verify with RS256 public key — returns the PKCS#11 status code CKR_OK (valid) or CKR_SIGNATURE_INVALID (rejected)
Sign a token first to verify it.
Note: All signing and verification operations execute in SoftHSM3 WASM — a reference PKCS#11 v3.2 implementation. Real key pairs are generated and cached per algorithm. Signature sizes match the actual FIPS 204 / PKCS#1 / ECDSA specifications. Generated keys are for educational purposes only.
IAM PQC Known Answer Tests
OpenID Connect · SAML 2.0 · FIPS 204 · FIPS 198-1 · NIST SP 800-132
Click Run validation tests to run 5 use-case scenarios. Evidence in this set: NIST ACVP-Server reference sample — Expected values copied from the public NIST ACVP-Server repository with immutable source identity.; Published standard KAT — Expected values printed in a cited standard or consensus RFC.; Functional round-trip — Output produced by an implementation is consumed by the same or paired implementation..
Reference samples from the public NIST ACVP-Server repository · OpenID Connect · SAML 2.0 · FIPS 204 · FIPS 198-1 · NIST SP 800-132 · Generated keys are for educational use only.
Known issue: the password-derivation (PBKDF2) test errors with CKR_ARGUMENTS_BAD — this is a softhsm-wasm C_DeriveKey binding limitation, not a cryptographic failure. The other KAT rows are unaffected.
No keys yet — click Execute to run the provisioning flow.
Try it
Sign a token with RS256 and then with an ML-DSA variant. What in the Size Impact Analysis grows most?
Next step
Turn it into a plan: Hybrid Transition PlannerThis tool practises the Identity & Access Management with PQC module, phase 5 (Pilots & Migration); Hybrid Transition Planner produces a deliverable of that phase.
Related content
Next in HSM / PKCS#11