TK TaskKit
Developer Tools

JWT Encoder

Sign JSON Web Tokens locally with HS, RS, PS, or ES algorithms. Header, payload, and signing key never leave your browser.

Algorithm
Header
Custom claims
Payload
Custom claims
Header (raw)
Payload (raw)
Signing keyHS256
Signed token

Pick an algorithm, edit the header and payload, paste your signing key, and your signed token appears here.

Inputs stay on this device. Every developer tool on TaskKit runs entirely in your browser. Tokens, payloads, and pasted text are not transmitted to TaskKit servers or third parties.

What this tool does

This JWT encoder signs a JSON Web Token entirely in your browser. Choose an algorithm, edit the header and payload, paste your signing key (a shared secret for HMAC; a PKCS#8 PEM private key for RSA or ECDSA), and you get a complete signed token you can paste into a request, a fixture, or a config.

Supported algorithms: HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512, and EdDSA (Ed25519). alg: none is supported as well, but the UI flags it as the unsigned-token security risk it is.

Key input accepts what most CLI tools actually emit. RSA private keys can be pasted as PKCS#8 (BEGIN PRIVATE KEY) or as PKCS#1 (BEGIN RSA PRIVATE KEY) — TaskKit wraps the PKCS#1 body into PKCS#8 with a small in-house ASN.1 reader before handing it to WebCrypto, no openssl pkcs8 -topk8 step needed. EdDSA accepts the 32-byte private seed as 64 hex chars, 43 base64url chars, a JWK, or a PKCS#8 PEM. Encrypted PKCS#8 keys (BEGIN ENCRYPTED PRIVATE KEY) are rejected with a one-line decryption hint; SEC1 EC private keys (BEGIN EC PRIVATE KEY) are rejected with a one-line conversion hint.

When you'd use it

  • Generating a token for a local integration test where you control both ends.
  • Producing a fixture for a unit test that needs a token-shaped string with a real signature.
  • Reproducing a bug from a working token by tweaking a claim and re-signing with the same key.
  • Building an example token for a teammate during a debugging session, without exposing the secret on a shared site.

How it works

Signing uses crypto.subtle.sign, the browser's built-in WebCrypto API. HMAC keys are imported from raw bytes; RSA and ECDSA private keys are imported as PKCS#8 (PKCS#1 is converted on the fly). EdDSA goes through @noble/ed25519 since WebCrypto's Ed25519 support is still patchy. The encoder builds base64url(header).base64url(payload).base64url(signature) and that's the token.

The header's alg field is always overwritten to match the algorithm you picked, even if you typed something different in the header textarea. typ: "JWT" is added by default if you didn't include it. Custom header fields (kid, x5t, anything else) are preserved.

The header, payload, and signing key never leave your browser. There is no server step.

Notes

Where do I get a private key from? For RSA: openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048 produces a PKCS#8 PEM (BEGIN PRIVATE KEY). Older PKCS#1 blocks (BEGIN RSA PRIVATE KEY) are accepted directly — no conversion step needed. For EdDSA: openssl genpkey -algorithm Ed25519 works and TaskKit reads the resulting PKCS#8 PEM. SEC1 EC private keys (BEGIN EC PRIVATE KEY) need to be converted first with openssl pkcs8 -topk8 -nocrypt -in sec1.pem -out pkcs8.pem.

Should I sign tokens with alg: none? Almost never. The unsigned token has no integrity protection and any verifier that accepts it can be tricked. The encoder produces it for completeness and explicitly warns; treat the output as test-only.

HS vs RS for new code? RS256 (or ES256) when an external party verifies — they only need the public key. HS256 when the same service is on both sides.

Related tools