demo · v137

JWT EdDSA

A real Ed25519 use case the spec authors call out: signing JSON Web Tokens with alg: EdDSA. Smaller signatures than RS256, faster verify, and previously required pulling in tweetnacl or similar. Now crypto.subtle does it natively.

probing…

token

(generate + sign first)
jwk public key(none)
decoded header
decoded payload
signature
verify

the code

// Generate a keypair as before, but export as JWK for portability.
const kp = await crypto.subtle.generateKey(
  { name: "Ed25519" }, true, ["sign", "verify"]);
const jwk = await crypto.subtle.exportKey("jwk", kp.publicKey);

// Encode header + payload as base64url, sign the concatenation.
const enc = (obj) => b64url(new TextEncoder().encode(JSON.stringify(obj)));
const head = enc({ alg: "EdDSA", typ: "JWT" });
const body = enc(payload);
const data = new TextEncoder().encode(head + "." + body);
const sig  = await crypto.subtle.sign("Ed25519", kp.privateKey, data);
const jwt  = head + "." + body + "." + b64urlBytes(sig);

// Verify on the receiving side - bytes only, no library.
const [h, p, s] = jwt.split(".");
await crypto.subtle.verify("Ed25519", kp.publicKey,
  decodeB64url(s), new TextEncoder().encode(h + "." + p));

see also