How to create a signed JWT
- Choose the algorithm. The header’s
"alg"follows your choice automatically. - Edit the payload. Use the claim buttons to set
iat(issued at) to the current time,expa number of minutes ahead,nbf(not before) to now, or a fresh randomjti(token ID). Every time claim is listed in UTC underneath, with how far it is from now. - Supply the key: a shared secret for HS256/384/512, or a private key for the RSA, ECDSA and EdDSA families. No key handy? Generate a key pair creates one in the page.
- Copy the token, or press Open in JWT decoder to inspect it and check the signature in the JWT decoder.
The token is shown in three colours: header, payload and signature, separated by dots. Each part is Base64URL without padding, so it is safe in URLs and HTTP headers.
Choosing an algorithm
- HS256, HS384, HS512 — HMAC with a shared secret. Whoever can verify a token can also mint one, so use them when the issuer and the verifier are the same service.
- RS256, RS384, RS512 — RSA signatures (PKCS#1 v1.5). The private key signs; anyone holding the public key can verify. The most widely supported asymmetric choice, and the default in many identity providers.
- PS256, PS384, PS512 — RSA-PSS, the probabilistic padding scheme. Same keys as RS*, but every signature differs, even for identical input.
- ES256, ES384, ES512 — ECDSA on P-256, P-384 and P-521. Much shorter keys and signatures than RSA. Note that ES512 uses curve P-521, not “P-512”.
- EdDSA — Ed25519 signatures: fast, deterministic and compact. Available when your browser’s Web Crypto supports Ed25519; the page tells you if it does not.
- none — no signature at all. The page shows a warning, because any server that accepts such tokens lets anyone forge them.
Secrets and key sizes
RFC 7518 requires an HMAC key at least as long as the hash: 32 bytes for HS256, 48 for HS384 and 64 for HS512. Shorter secrets still produce a token, but the page warns, because a captured token lets an attacker guess weak secrets offline at enormous speed. Random secret fills in a value of the right strength.
Secrets can be read as plain text (UTF-8) or as Base64. Choose Base64 when your configuration stores the key as encoded bytes, such as the k member of a symmetric JWK; both the standard and URL-safe alphabets are accepted.
RSA keys must be 2048 bits or longer; smaller ones are flagged. ECDSA keys must match the curve of the algorithm, and a mismatch is reported in plain words, for example that ES256 needs a P-256 key.
Private key formats
Paste a PKCS#8 PEM (the block starting -----BEGIN PRIVATE KEY-----) or a private JWK, the JSON form with a "d" member. Older OpenSSL commands write PKCS#1 (BEGIN RSA PRIVATE KEY) or SEC1 (BEGIN EC PRIVATE KEY) files; Web Crypto cannot read those directly, so the page names the exact openssl pkcs8 -topk8 -nocrypt command that converts them. Passphrase-protected keys need decrypting first.
ECDSA signatures are emitted in the JOSE form, the raw r and s values joined together, rather than the DER structure some crypto libraries return. That is the format every JWT library expects.
Exact encoding and test vectors
By default the header and payload are compacted before encoding, the way most libraries do it, while keeping every number exactly as written: an ID like 12345678901234567890 is not rounded. Tick Encode JSON exactly as typed to encode your text byte for byte instead, whitespace included. Published test vectors depend on this; our test suite reproduces the HS256 example from RFC 7515 Appendix A.1 that way. The editor stores line breaks as LF, so vectors written with CRLF only match from code.
Duplicate claim names are rejected rather than encoded, because verifiers disagree about which value wins. Times in milliseconds, a common slip, are flagged; JWT times are whole seconds since 1970, and the Unix timestamp converter helps check them.
What stays private
Everything happens in the page: the header, claims, secret and keys are processed by Web Crypto in a background worker and are not saved anywhere, not even in this browser’s storage. Generated key pairs exist only until you close the tab. The decoder link carries the token in the part of the URL after #, which browsers do not send to servers, plus the public key when one exists, so the signature can be checked. Secrets and private keys are never put in a link. More on how the site is built in Security.
Examples
HS256 access token with a shared secret
A typical session token: subject, scope, and a one-hour lifetime. The 33-character secret meets the 32-byte minimum for HS256, so there is no warning.
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "user_8841",
"name": "Mina Okafor",
"scope": "orders:read orders:write",
"iat": 1791277200,
"exp": 1791280800
}pastekit-example-secret-key-2026!eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzg4NDEiLCJuYW1lIjoiTWluYSBPa2Fmb3IiLCJzY29wZSI6Im9yZGVyczpyZWFkIG9yZGVyczp3cml0ZSIsImlhdCI6MTc5MTI3NzIwMCwiZXhwIjoxNzkxMjgwODAwfQ.o1PWDdQChiPJQnOy5mkviomy5VZ_JBcFaAqtGIviEBwHS512 service token with a Base64 key
The 64-byte key is stored as Base64, so the secret is read as bytes rather than text. A key ID in the header tells the verifier which key to use.
{
"alg": "HS512",
"typ": "JWT",
"kid": "2026-10"
}{
"iss": "https://auth.example.com",
"aud": "billing-api",
"sub": "svc-reports",
"iat": 1791277200,
"exp": 1791278100
}U/9j5pj6oOj6DvV2GB0sGIJK8SOfkBxRfev1s3eJ6UOtGNQF7hj1lgxLTSj3JubwXf3lw/Lv2oRy38FyiRRXvQ==eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6IjIwMjYtMTAifQ.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJhdWQiOiJiaWxsaW5nLWFwaSIsInN1YiI6InN2Yy1yZXBvcnRzIiwiaWF0IjoxNzkxMjc3MjAwLCJleHAiOjE3OTEyNzgxMDB9.UZYGPRy8EEaFjOmDkuplCVdr7HX-EmVTdlVMfVHqIUGmRlj1iYOQ_GxdUcp7Q3yFquHHViTuyqev8WkvEwv8sgES256 token with a freshly generated key pair
Loading this example generates a new P-256 key pair in the page. ECDSA signatures are randomised, so the token changes each time; the decoder link includes the public key and verifies it.
{
"alg": "ES256",
"typ": "JWT"
}{
"iss": "https://id.example.org",
"sub": "device-17",
"aud": ["telemetry"],
"iat": 1791277200,
"exp": 1791363600
}Unsecured token for a unit test (alg none)
An unsigned token ends with a dot and an empty signature. Useful for checking that your server rejects it; never accept one in production.
{
"alg": "none",
"typ": "JWT"
}{
"sub": "test-user",
"role": "viewer"
}eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJ0ZXN0LXVzZXIiLCJyb2xlIjoidmlld2VyIn0.Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
The header says "alg": "HS256" but the selected algorithm is RS256 | The header JSON was edited by hand and no longer matches the algorithm picker. | Pick the algorithm again from the list, which rewrites “alg”, or correct the header yourself. |
The secret is 128 bits; RFC 7518 requires at least 256 bits (32 bytes) for HS256 | The HMAC secret is shorter than the hash output, which makes offline guessing practical. | Use a random secret of at least 32 bytes for HS256 (48 for HS384, 64 for HS512). The token is still produced so you can test. |
This is a PKCS#1 "RSA PRIVATE KEY"; Web Crypto needs PKCS#8 ("BEGIN PRIVATE KEY") | The key file uses the older RSA-specific PEM layout that browsers cannot import. | Run openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem and paste the new file. |
ES256 needs an EC private key on curve P-256, but this is an EC P-384 key | Each ECDSA algorithm is tied to one curve: ES256 to P-256, ES384 to P-384, ES512 to P-521. | Choose the algorithm that matches the key, or generate a new key pair for the algorithm you need. |
Signature does not match the supplied key (in the decoder)Explained | The decoder was given a different secret or public key, or a Base64 secret was entered as text there. | Use the decoder link, which carries the matching public key; for HMAC, paste the same text secret into the decoder. |
Frequently asked questions
Is it safe to paste a production signing key here?
The key is used by Web Crypto inside this tab and is never uploaded, stored or added to links. Even so, the safest habit is to keep production keys inside your secret manager and use generated test keys for experiments.
Why does my RS256 token look the same every time but ES256 does not?
RSA PKCS#1 v1.5 and HMAC signatures are deterministic, so identical input gives an identical token. ECDSA and RSA-PSS add randomness to every signature, so the token differs each time but still verifies with the same public key.
Which key does the decoder need to verify my token?
For HS algorithms, the same secret. For RS, PS, ES and EdDSA, the public key: the PEM or JWK shown under the generated pair, or the public half the page derives from your private key and puts in the decoder link.
What is the difference between EdDSA and Ed25519 in a JWT header?
EdDSA is the original JOSE algorithm name for Edwards-curve signatures, and with Ed25519 keys it is what most libraries emit and accept. Newer specifications also define the fully-specified name Ed25519; this page signs with “EdDSA” for compatibility.
Does the encoder check that the token is still valid?
It shows iat, nbf and exp in UTC with their distance from now, and warns when exp is not after nbf or when a time looks like milliseconds. Validation against a clock is the verifier’s job, which the decoder also performs.
Can I create an encrypted token (JWE)?
No. This page creates signed tokens (JWS), whose payload anyone can read. Do not put passwords or personal data in the claims unless the token is also encrypted by your own tooling.