Skip to content
ALL DEVELOPER TOOLS56
JSON FormatterTXT → JSONJSON to CSVJSON → CSVCSV to JSONCSV → JSONSQL FormatterSQL → SQLMarkdown to HTMLMD → HTMLHTML to MarkdownHTML → MDXML FormatterXML → XMLBase64 Encode/DecodeTXT → B64URL Encode/DecodeTXT → URLJWT DecoderJWT → JSONHTML Entity Encode/DecodeTXT → HTMLUUID Generator— → UUIDPassword Generator— → TXTHash GeneratorTXT → HASHLorem Ipsum Generator— → TXTQR Code GeneratorTXT → PNGColor Picker & Converter— → HEXCSS Gradient Generator— → CSSBox Shadow Generator— → CSSRegex TesterTXT → MATCHCron Expression GeneratorTXT → CRONTimestamp ConverterNUM → DATEText DiffTXT → DIFFText Case ConverterTXT → TXTWord CounterTXT → STATSSubtitle ConverterSUBS → SRT · VTT · ASSYAML to JSONYAML → JSONJSON to YAMLJSON → YAMLYAML FormatterYAML → YAMLJSON MinifyJSON → JSONSort & Dedupe LinesTXT → TXTLine Ending ConverterTXT → CRLF · LF · CRXLSX to CSVXLSX → CSVCharset ConverterTEXT → UTF-8HAR ViewerHAR → TABLE · HARJWT EncoderJSON → JWTHMAC GeneratorTXT → MACFile ChecksumFILE → VERDICTWi-Fi QR Code Generator— → QRChmod CalculatorOCTAL → RWXHTTP Status CodesCODE → MEANINGByte ConverterSIZE → UNITSTime Zone ConverterTIME → ZONESAspect Ratio CalculatorSIZE → RATIOURL ParserURL → PARTSExtract ArchiveARCHIVE → FILES · ZIPCreate ZIPFILES → ZIPUnzip FilesZIP → FILESDOCX to MarkdownDOCX → MDSVG OptimizerSVG → SVGBarcode Generator— → BARCODEQR Code ReaderIMG → TEXTVCF to CSVVCF → CSVICS to CSVICS → CSVCSV to Markdown TableCSV → MDBcrypt Generator— → HASH
ENGINE SUBTLECRYPTOACCEPTS NONE

JWT Encoder

SUBTLECRYPTOTOOL 155 OF 190

JWT Encoder — Sign HS256, HS384 & HS512 Tokens

Build the header and payload, sign with your secret, and copy the token — a JWT is signed, not encrypted, so every claim in it stays readable.

ENGINESUBTLECRYPTO
ACCEPTSNONE
MAX SIZENONE
UPLOADNEVER
01Edit the Header and Payload panes, or stamp iat, nbf and exp from the chips under TIME CLAIMS.
02Type your own SIGNING SECRET and set Secret encoding to Text, Hex or Base64.
03Copy the signed token — it is signed, not encrypted, so anyone holding it can read every claim in it.

About JWT Encoder

A JSON Web Token is three base64url segments joined by dots: a header saying how it was signed, a payload of claims, and a signature over the first two. This page builds one. Edit the header and payload as JSON, pick HS256, HS384 or HS512, type the shared secret, and the token is signed in the tab with the browser's own Web Crypto — nothing is uploaded and the secret is used nowhere else. The important thing about a JWT is what it does not do. It is signed, not encrypted. Both leading segments are base64url, an encoding with no key involved, so anyone holding the token can read every claim in it, including anyone who finds it in a log line. Put nothing secret in the payload. Only HMAC algorithms are offered here: RS256 and ES256 sign with a private key, and a page that asks you to paste one into a text box is a credential-collection pattern regardless of intent. The claim helpers compute iat, nbf and exp in seconds rather than milliseconds, and each edit rewrites one span of your payload text, so a 64-bit id keeps all of its digits.

Questions

Can I sign with RS256? I have the private key.

No, and not because it was forgotten. RS256, PS256 and ES256 sign with an RSA or elliptic-curve private key, which would mean pasting a private key into a web page — a credential-handling pattern this site will not ship, whatever the page then does with it. HS256, HS384 and HS512 cover every case where both sides hold the same secret, which is most internal APIs. For an asymmetric token, sign it where the private key already lives: your language's JWT library, or the openssl command line. The JWT Decoder here will still inspect the result.

Is the payload encrypted? Can I put a password in it?

No, and no. A JWT is signed, not encrypted. The header and payload are base64url — an encoding, reversible by anyone, with no key involved at all. Paste any token into this site's JWT Decoder, or into any base64 decoder, and every claim comes straight back out. The signature proves the token has not been altered and that whoever made it held the secret; it hides nothing whatsoever. Treat the payload as public: a user id and a role are fine, an email address is a judgement call, and a password or an API key is never fine.

My token is rejected with 'invalid signature' and I copied it exactly.

Three usual causes, in order. First the secret's encoding: an API that gives you a base64 or hex secret expects those bytes, and typing it with the encoding left on Text makes a different key out of the same characters. The rail prints the key length in bytes — compare it with what your library reports. Second the algorithm: the header's alg has to match what the verifier expects, and this page refuses to sign at all while the picker and the header disagree, rather than emitting a token that cannot verify. Third, whitespace copied along with the token.

Why does my exp claim say 1970, or the year 56000?

Because exp, iat and nbf are seconds since 1 January 1970, not milliseconds. Date.now() in JavaScript gives milliseconds, and pasting that straight into exp produces a token that expires roughly fifty-four thousand years from now, which some verifiers reject outright as implausible. Dividing by a thousand and rounding down fixes it. The claim buttons in the rail do exactly that, and print the resulting instant in UTC underneath with a plain-English distance from now, so a wrong magnitude is visible on the page instead of being discovered later by somebody else's verifier.

Does the secret I type here get sent anywhere?

No. Signing happens in this tab through the browser's Web Crypto API: there is no request, no server, and no analytics event carrying the secret. What that does not do is make the resulting token trustworthy — a token is only as strong as the secret behind it, and a secret weak enough to guess makes a token anyone can forge. The page seeds jwt.io's debugger placeholder, your-256-bit-secret, so that it produces something on load, and warns on screen for as long as that placeholder is still in the box. It is worth knowing what that string is not: it appears in no JWT or JOSE RFC, and it is 19 bytes of text — 152 bits — whatever its name says. RFC 7515's own HS256 worked example signs a different header and payload with a 64-byte key.

Is my file uploaded to a server?

No. Transmute processes everything locally in your browser using JavaScript and WebAssembly. Your files never leave your device — there is no server, no upload, no cloud processing.

Related