Build and sign JWT tokens
Compose a payload, pick an HMAC algorithm, sign with your secret — get a ready-to-use JWT. Decode mode also lets you inspect existing tokens. Runs in your browser.
Result will appear here…
How to build and sign a JWT: a complete step-by-step guide
A JSON Web Token (RFC 7519) is a compact, URL-safe credential composed of three base64url segments — header.payload.signature. This encoder follows the JWS Compact Serialization (RFC 7515): it serializes your header and claims, base64url-encodes them, then signs with HMAC via the browser's Web Crypto SubtleCrypto.sign. No bytes ever leave your device.
- 01
Pick encode or decode mode
Switch to Encode to mint a fresh token by composing a payload and signing with a secret. Use Decode to inspect an existing JWT without verifying its signature — handy for cross-checking what an issuer wrote into the claims.
Encode is the typical flow for test fixtures, prototyping an auth provider, or stubbing webhook payloads. For verifying a token against a JWKS or PEM, sign in your backend; for inspection only, the JWT Decoder is a dedicated read-only view.
RFC 7519JWS compactencodedecodetest fixturesmode · selectorencodeEncode · Decode
set · readyRFC 7515 - 02
Compose payload claims
The payload is a JSON object of registered claims (
iss,sub,aud,exp,iat,nbf,jti) plus any custom fields your app needs — scopes, roles, tenant ID, feature flags. All claims are public; anything sensitive belongs encrypted (JWE) or behind an opaque session reference.Timestamps are Unix epoch seconds, not milliseconds. For a one-hour expiry:
Math.floor(Date.now()/1000) + 3600. JSON is parsed strictly per RFC 8259 — pre-flight with the JSON Validator if needed.isssubexpiatUnix epochregistered claimspayload · json3 claims{ "sub": "alice", "iat": 1516239022, "exp": 1516242622 }78 B · 3 linesRFC 7519 § 4 - 03
Choose HMAC algorithm and secret
HMAC algorithms (
HS256,HS384,HS512) are symmetric: the same shared secret signs and verifies.HS256uses HMAC-SHA-256 — the default for most providers. Step up toHS512only if your threat model demands it;HS256is already cryptographically strong.For asymmetric signing (
RS256RSA-PKCS1,PS256RSA-PSS,ES256ECDSA P-256,EdDSAEd25519), generate keys with the RSA or Ed25519 tools and sign server-side — private keys should never touch a browser.HS256HS384HS512HMACsymmetricWeb Cryptoheader · alg+typHS256{ "alg": "HS256", "typ": "JWT" }36 B · 1 segmentRFC 7515 § 4.1 - 04
Sign, copy, and ship the token
The encoder base64url-encodes the header and payload (no padding,
+/swapped for-_), joins with a dot, and feeds the result throughcrypto.subtle.signwith your HMAC key. The signature is appended as a third base64url segment — three dot-separated parts, ready for anAuthorization: Bearerheader.Verify your token by pasting it into the JWT Decoder or run
jwt.verify(token, secret)in your backend. To inspect the raw segments byte-by-byte, the Base64 Decoder handles URL-safe input.base64urlBearer tokenclipboardprivacy-firstRFC 4648 § 5output · signed jwt3 segmentseyJhbGci….eyJzdWIi….SflKxwRJ…
210 B · 1 line0 outbound
Encoding without surprises
Always UTF-8 first
Use TextEncoder / TextDecoder for bytes ↔ string conversion. btoa alone breaks on non-ASCII.
URL-safe vs standard Base64
Standard uses +, /, =; URL-safe swaps to -, _, no padding. Don’t mix them.
Hashes aren’t passwords
SHA-256 is fast; that’s good for fingerprints, bad for passwords. Use bcrypt / argon2 for credentials.
Watch padding rules
Some decoders are strict about = padding, others auto-pad. If round-trips fail at exactly 1 or 2 bytes, check padding.
Use Web Crypto for keys
Generate cryptographic keys via crypto.subtle, never Math.random. The latter is predictable.
JWT decode ≠ verify
Decoding a JWT just splits and base64-decodes. Verification needs the issuer’s public key / shared secret.
When to build a JWT
Auth flows, test fixtures, signed webhooks.
Auth integration tests
Mint test tokens with known claims for backend tests. Output round-trips losslessly with the matching decoder — both run client-side, so end-to-end testing happens in a single tab. Encoding flows through TextEncoder for predictable UTF-8 semantics.
RFC-compliantAuth provider mocking
Stub a JWT issuer locally during development. Web Crypto's subtle.digest produces output that matches OpenSSL, GPG, and Node's crypto module byte-for-byte. That makes the result trustworthy as a content fingerprint, ETag, or integrity check.
OpenSSL-matchedSigned webhooks
Carry tamper-proof claims between services. Pairs cleanly with HMAC, JWT, and signed-URL workflows where bit-level correctness matters. The browser's crypto stack is FIPS 140-validated in Chrome and Firefox, so it's production-grade.
losslessShort-lived API keys
Issue scoped tokens with an exp claim. Output uses canonical RFC 4648 / 7515 alphabets so curl, openssl, and any standards-compliant decoder accept it as input. URL-safe variants drop padding for tokens that travel in query strings.
byte-identicalTime-bound URLs
Embed signed JWTs as access tokens in URLs. Heavy hashing runs through useMemo so large inputs don't block typing. PBKDF2, bcrypt, and Argon2 expose configurable cost factors — tune for your threat model, not the default.
spec-gradeCross-service trust
Microservices verify each other via shared secrets. Same input plus same options always yields identical bytes. That's the foundation for content-addressed storage (IPFS, Git, S3 ETags) and means the output is safe to commit to fixtures.
production-readyFrequently asked questions
Something missing?
Tell us what you need. We ship the top requests every two weeks.