What signing a JWT involves
A signed JWT is a JSON Web Signature (RFC 7515) whose payload is the claims set from RFC 7519. The encoder builds it in three steps. It writes the header {"alg":"HS256","typ":"JWT"}, with whichever algorithm you picked. It re-serialises your payload with JSON.stringify, which removes whitespace and keeps key order. It base64url-encodes both and joins them with a dot to form the signing input. Then the Web Crypto API computes an HMAC over that string using your secret and appends the result as the third segment.
The secret is converted to bytes as plain UTF-8 text. It is not base64-decoded first, so a secret that another system stores in base64 must be decoded before you paste it, or the signatures will not match.
Algorithms offered
| Name | Hash used by HMAC | Signature length (base64url) |
|---|---|---|
| HS256 | SHA-256 | 43 characters |
| HS384 | SHA-384 | 64 characters |
| HS512 | SHA-512 | 86 characters |
These are the symmetric algorithms of RFC 7518 section 3.2. The same secret both signs and verifies, so there are no RSA or ECDSA options, which would need a private key. RFC 7518 says the key should be at least as long as the hash output, which is 32 bytes for HS256. The tool does not enforce that, so a short secret signs without complaint.
Worked example
Signing {"sub":"1234567890","name":"Jane Doe","iat":1700000000} with HS256 and the default secret your-256-bit-secret yields:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzAwMDAwMDAwfQ.
G2Fn2qE65tMTYs_mW1CVKaLoDWR0nkWkyL0H6Dc12IY
(shown on three lines; the real token has no line breaks). The iat value 1700000000 is 22:13:20 UTC on 14 November 2023. Recomputing the HMAC-SHA256 of the first two segments with another library gives the same final segment.
Security notes
- A shared secret is a signing key. Anyone who knows it can mint tokens your server will accept. Use throwaway secrets for tests and fixtures, never the production value, and treat anything typed into a web page as exposed.
- Nothing is added for you. The payload is signed exactly as typed. Set
exp,iatandaudyourself, in Unix seconds. - Signing is not encryption. The claims stay readable by anyone holding the token.
- Servers should pin the accepted algorithm instead of trusting the header's
alg, which prevents downgrade tricks such asalg: none.
To read a token you already have, use the JWT decoder. The hash generator shows the plain digests that HMAC builds on.