Logo

Online Tools

JWS Sign Message

Sign a payload as a compact JWS or JWT in your browser using HS256, RS256, PS256, or ES256 with a shared secret, PEM private key, or JWK. Read more

Sign a payload as a compact JWS

This page builds a compact JWSheader.payload.signature — from the payload you enter and the key you supply. Everything runs in your browser; nothing is uploaded.

The payload is used exactly as typed. A JWT is simply a JWS whose payload is a JSON claims set, so paste JSON such as {"iss":"example","exp":1700003600} to produce one. Any other UTF-8 text is signed as-is, which is valid JWS but not a JWT.

How to sign

  1. Enter the payload.
  2. Select the algorithm.
  3. Choose the key type and paste the key:
    • UTF-8, Hex, or Base64 — the shared secret for HS256, HS384, or HS512, in whichever spelling you have it. A passphrase such as s3cr3t is UTF-8. Base64 accepts both the standard and the URL-safe alphabet, with or without = padding, so the k value copied straight out of a JWK works here too.
    • Pem Text — an RSA or EC private key for RS*, PS*, or ES*. Add the passphrase if the PEM is encrypted.
    • JWK — a private JSON Web Key (d present for RSA and EC), or "kty": "oct" for HMAC. A whole JWK Set is not accepted here: signing has no signature to test against, so there would be no way to tell which of its keys you meant.
  4. Edit the Header JSON if you need more than the default { "typ": "JWT" }kid, cty, crit, x5t, or anything else your verifier expects. Clear the field entirely for a header with nothing but alg.
  5. Sign, then use the swap button to send the token straight to JWS Verify and check it against the matching public key or secret.

How the header is built

Whatever JSON is in the Header field becomes the JOSE header, then alg is overwritten with the algorithm you selected. That one override means the header can never advertise an algorithm different from the one that actually signed the token; everything else is yours to set.

typ defaults to "JWT" because that is what the overwhelming majority of these tokens are, and it is the value most verifiers expect to see. Delete it if you are signing something that is not a JWT. kid is worth adding whenever the verifier picks its key out of a JWK Set — JWS Verify uses it for exactly that.

Choosing an algorithm

HS256 needs both sides to hold the same secret, which is fine inside one system but means every verifier can also mint tokens. RS256 and ES256 split that: you sign with a private key and publish only the public key, so verifiers can check tokens without being able to issue them. ES256 produces far smaller signatures than RS256 at a comparable security level. PS* is the modern RSA padding and is preferred over RS* for new designs.

A short exp matters more than the algorithm. A signed token stays valid until it expires, and it cannot be revoked by the issuer once handed out.

Each ECDSA algorithm is tied to one curve: ES256 to P-256, ES384 to P-384, ES512 to P-521. Pairing an algorithm with a key on a different curve is refused here, because the resulting token would be rejected by any verifier that follows the specification.

EdDSA (Ed25519) is not supported yet. Out of scope on this page: JWE, the JSON serializations, detached payloads, and unencoded payloads ("b64": false, RFC 7797).

Keep production keys out of here

Prefer a throwaway key when you are only checking a format or reproducing a bug. Signing is local, but a private key pasted into any browser window is still on your clipboard and on the screen behind you. Two page features can also outlive the moment: Remember Input stores the payload, key, passphrase, and header in your browser’s local storage, and Share encodes them into a link. Both are opt-in and neither reaches a server, but a link built from a real signing key is a real signing key. Generate a test pair with RSA Key Generator or ECDSA Key Generator instead.

JWS signing FAQ

Does the payload have to be JSON?

No. JWS signs arbitrary bytes. JSON is only required if you want the result to be a JWT that other JWT libraries will accept.

Why is my output empty?

An empty payload produces no token. Errors appear in the output box, for example Key is blank., Header is not valid JSON., or a message explaining that the chosen algorithm does not match the key type.

Can I sign with alg set to none?

No. An unsigned token offers no protection and is a known source of verification bypasses, so it cannot be produced here.

How do I get a key pair to test with?

Generate one with RSA Key Generator or ECDSA Key Generator, sign with the private key here, and verify with the public key on JWS Verify.

Input
Advertisement
Output
Share Link
Settings
Key
Advertisement