JWT Signing (RS256)
Create a JSON Web Token signed with RSA-SHA256 on wasm runtimes such as Cloudflare Workers, Deno, or the browser. This is the standard authentication flow for GitHub Apps, Google service accounts, and many OAuth 2.0 providers.
sh
cargo add wasm_web_crypto --features sign,keyImport a private key and sign
Import a PKCS#8 DER private key, sign the header.payload string, and append the base64url-encoded signature.
rust
use wasm_web_crypto::{Algorithm, Hash, KeyFormat, KeyUsage, SubtleCrypto};
let subtle = SubtleCrypto::new()?;
// Import a PKCS#8 DER private key
let key = subtle.import_key(
KeyFormat::Pkcs8,
&private_key_der,
&Algorithm::RsassaPkcs1v15 { hash: Hash::Sha256 },
false,
&[KeyUsage::Sign],
).await?;
// Sign the JWT header.payload
let signature = subtle.sign(
&Algorithm::RsassaPkcs1v15 { hash: Hash::Sha256 },
&key,
signing_input.as_bytes(),
).await?;
let jwt = format!("{}.{}", signing_input, signature.to_base64url());Verify with a public key
rust
let public_key = subtle.import_key(
KeyFormat::Spki,
&public_key_der,
&Algorithm::RsassaPkcs1v15 { hash: Hash::Sha256 },
false,
&[KeyUsage::Verify],
).await?;
let valid = subtle.verify(
&Algorithm::RsassaPkcs1v15 { hash: Hash::Sha256 },
&public_key,
signature.to_bytes(),
signing_input.as_bytes(),
).await?;
assert!(valid);PEM to DER conversion
Web Crypto API accepts DER binary, not PEM text. To convert:
- Remove
-----BEGIN PRIVATE KEY-----/-----END PRIVATE KEY-----lines - Base64-decode the remaining content
- Pass the resulting bytes to
import_key