XConvert
Downloads
Pricing

JWT Encoder Online

Encode JWT data into a JWTSIGN output using a fast, client-only JWT encoder that runs directly in your browser.

Header
Payload (JSON)
Secret
Signed JWT
Token will appear here once you click Sign JWT.

How to Sign a JWT Online

  1. Pick a Signing Algorithm: Choose from the dropdown — HS256 / HS384 / HS512 (HMAC with a shared secret), RS256 / RS384 / RS512 (RSA private key, PKCS#1 v1.5), ES256 / ES384 / ES512 (ECDSA on P-256 / P-384 / P-521), or EdDSA (Ed25519). HS* is fine for a single monolith; use RS*, ES*, or EdDSA when verifiers are separate services.
  2. Enter the Payload JSON: Paste your claims object — for example {"sub":"1234567890","name":"Alice","iat":1716700000,"exp":1716703600}. RFC 7519 registered claims (iss, sub, aud, exp, nbf, iat, jti) plus any custom claims your API expects. Time values are seconds since 1970-01-01 UTC, not milliseconds.
  3. Provide the Secret or Private Key: For HS* paste the shared secret string (≥32 bytes recommended for HS256). For RS* / ES* / EdDSA paste a PEM-formatted private key beginning with -----BEGIN PRIVATE KEY----- (PKCS#8) or -----BEGIN RSA PRIVATE KEY----- (PKCS#1).
  4. Sign and Copy: Click Sign. The output is the three-part token header.payload.signature (base64url, no padding). Everything happens in your browser — no key ever leaves the tab.

Why Use a JWT Encoder?

JSON Web Tokens are the de-facto bearer credential for REST and GraphQL APIs in 2026 — short, URL-safe, and self-contained so the resource server can authorize a request without a database round-trip. Hand-building one with a CLI means juggling base64url, header JSON, and an OpenSSL command per algorithm; an in-browser encoder turns it into a 30-second loop. Common reasons to mint one yourself:

  • API debugging — generate a token with a known payload ({"sub":"test-user","role":"admin","exp":...}) to reproduce a 401 in staging without dragging in your full auth flow.
  • Integration tests — drop a hand-signed token into a Postman / curl / k6 script so the test rig doesn't have to call your real identity provider on every run.
  • Service-to-service auth — sign a short-lived (exp 60-300 s) RS256 token in one microservice and verify it with the public key in another, no shared secret required.
  • OAuth2 / OIDC client assertions — private_key_jwt client authentication (RFC 7523) needs an RS256 or ES256-signed JWT in the token request. Mint one here, paste it as client_assertion.
  • Webhook signing — some platforms (Auth0 Actions, Stripe Connect onboarding links) expect a signed JWT as proof the caller knew a shared secret without sending it on the wire.
  • Learning and security review — flip between HS256 and RS256 to see how header/signature lengths change, or experiment with the JWT decoder to confirm your token round-trips.

JWT Signing Algorithm Comparison

Algorithm Key type Signature size Security (2026) When to pick it
HS256 / HS384 / HS512 Symmetric secret (HMAC-SHA-2) 32 / 48 / 64 bytes Strong if secret ≥ 32 bytes and never shared with verifiers Single monolith that both signs and verifies
RS256 / RS384 / RS512 RSA 2048-bit+ private key (PKCS#1 v1.5) 256 bytes (2048-bit key) Strong; ubiquitous library support Distributed systems; publish the public key via JWKS
PS256 / PS384 / PS512 RSA 2048-bit+ (RSASSA-PSS) 256 bytes Stronger than PKCS#1 v1.5, randomised padding New systems that need RSA but want modern padding
ES256 / ES384 / ES512 ECDSA P-256 / P-384 / P-521 64 / 96 / 132 bytes Equivalent to RSA-3072 / 7680 / 15360 at 1/40th the size Cookies, mobile clients, anywhere signature bytes matter
EdDSA (Ed25519) 32-byte Edwards-curve key 64 bytes State of the art — deterministic, no nonce-reuse foot-gun New greenfield services without RSA compatibility need
none (no signature) 0 bytes UNSAFE — accepts any forged token Never. Reject unconditionally on the verifier side.

Sources: Auth0 — RS256 vs HS256, Scott Brady — Which Signing Algorithm Should I Use?.

RFC 7519 Registered Claims

Claim Name Type Notes
iss Issuer string / URI Identifies who minted the token. Verifiers should pin a known value.
sub Subject string The principal — usually a user ID. Unique within the issuer.
aud Audience string OR array of strings RFC 7519 §4.1.3 allows either; verifier MUST reject if its own identifier isn't in the list.
exp Expiration Time NumericDate (seconds since epoch, UTC) After this instant the token MUST be rejected. Use Math.floor(Date.now()/1000)+3600 for "+1 h".
nbf Not Before NumericDate Token MUST be rejected if used before this instant.
iat Issued At NumericDate When the token was signed. Useful for max-age policies.
jti JWT ID string Unique per token. Lets the verifier blacklist or detect replay.

Frequently Asked Questions

Should I pick RS256 or HS256?

Use HS256 only when the same single service both signs and verifies — for example a small monolith with one secret in env vars. The moment another service (a microservice, a mobile app, a partner API) needs to verify your tokens, switch to RS256 (or ES256 / EdDSA). With RS* you publish a public key — usually at a JWKS endpoint like /.well-known/jwks.json — and verifiers can validate without you ever sharing the signing material. Auth0, AWS Cognito, Okta, Keycloak, and Firebase Auth all default to RS256 for that reason.

Why must I reject the none algorithm?

The JWS spec defined alg: "none" for tokens whose integrity is guaranteed by some other channel — but most libraries historically accepted a none-signed token without checking, meaning an attacker could strip the signature, set "alg":"none", and the verifier would treat the forged payload as authentic. The bug class is so common it has its own family of CVEs (e.g. CVE-2021-44878 in pac4j-jwt); algorithm-confusion vulnerabilities are a well-documented risk class across JWT libraries. Real fix: pass an explicit allow-list of algorithms (["RS256"]) to jwt.verify() and reject everything else, including case variants like nOnE. There is no legitimate production use case for unsigned JWTs.

What format is exp — milliseconds or seconds?

Seconds since 1970-01-01T00:00:00Z UTC, as a JSON number (RFC 7519 §2 calls this a NumericDate). The classic bug is passing Date.now() directly (milliseconds) — your token then expires roughly in the year 50,000 or fails immediately depending on the verifier. Always use Math.floor(Date.now() / 1000) in JavaScript or int(time.time()) in Python.

Can aud be an array or only a single string?

Both. RFC 7519 §4.1.3 says "In the general case, the aud value is an array of case-sensitive strings... In the special case when the JWT has one audience, the aud value MAY be a single case-sensitive string." Verifiers MUST check that their own identifier appears in the array (or matches the single string). If your token will be consumed by multiple APIs, use an array — "aud":["https://api.example.com","https://reports.example.com"].

RS256 vs ES256 — which should I prefer for new code?

ES256 if the signature size matters (cookies, mobile, IoT, JWTs in URLs) — 64 bytes vs RS256's 256. ECDSA on P-256 gives ~128-bit security, equivalent to a 3072-bit RSA key. Caveats: ECDSA requires a high-quality random nonce per signature; reuse leaks the private key (the PlayStation 3 hack). If you don't want to think about that, pick EdDSA (Ed25519) instead — it's deterministic, has no nonce, and is the modern best-practice default. Stick with RS256 only if you need broad library compatibility (e.g. legacy SAML/OIDC ecosystems where some verifiers still don't ship ECDSA).

How do I handle key rotation — what is the kid header?

kid (Key ID) is an optional JOSE header that names which key signed the token. The verifier looks up that ID in a JWKS (https://your-domain/.well-known/jwks.json) to find the matching public key. During rotation you publish both the old and new keys in the JWKS, start signing new tokens with the new kid, and let existing tokens verify against the old key until they expire. After the longest exp window passes, drop the old key. Without kid, rotation is a hard cutover and any token signed before the swap immediately fails. Add it as {"alg":"RS256","kid":"2026-05-key-1","typ":"JWT"} in the header.

How long should exp be?

Depends on the token's job. Access tokens that grant API access should be short — 5 to 60 minutes is typical (Google access tokens are 1 hour, AWS STS defaults to 1 hour). Refresh tokens that mint new access tokens can live longer (days to weeks) but should be opaque server-side records, not JWTs, so they can be revoked. ID tokens (OIDC) usually mirror access-token lifetime. Shorter exp = smaller damage window if a token leaks, but more refresh chatter; tune to your threat model.

Is my secret strong enough for HS256?

HS256 is HMAC-SHA-256, which expects a key at least as long as the hash output — 32 bytes (256 bits) of true entropy. A user-chosen password like "hunter2" has perhaps 20 bits and is trivially brute-forceable offline once an attacker captures one token. Generate with openssl rand -base64 32, crypto.randomBytes(32).toString('base64'), or use the password generator with length 44 (which gives 32 bytes once base64-decoded). For HS384 use 48 bytes, HS512 64 bytes.

Does this tool send my key to a server?

No. JWT signing happens entirely in your browser via the Web Crypto API — neither your payload nor your private key ever leaves the tab. Close the page and the key is gone from memory. If you need to inspect a signed token, the JWT decoder is also client-side and read-only. Format your payload first with the JSON formatter if it's compact / minified.

Related Generate tools
Nanoid GeneratorUlid GeneratorKsuid GeneratorFake Name GeneratorFake Email GeneratorFake Address GeneratorFake Phone GeneratorRandom Ip

Image Tools

Image CompressorCompress JPEGCompress PNGCompress GIFCompress WebPImage ConverterJPG ConverterImage Resizer

Video Tools

Video CompressorCompress MP4MP4 to GIFVideo to GIFVideo ConverterMP4 ConverterVideo Cutter

Audio Tools

Audio CompressorCompress MP3Compress WAVAudio ConverterMP3 ConverterFLAC to MP3Audio Cutter

Document Tools

Compress PDFMerge Images to PDFSplit PDFPDF to JPGUnzip FilesRAR Extractor
© 2026 XConvert.com. All Rights Reserved.
About UsPrivacy PolicyTerms of ServiceContactHelp Us Grow