跳到主要内容
ecdsa.com

JWT 签名工具

选择算法,粘贴私钥或共享密钥,再填写声明:令牌会随输入实时签名,用密钥的公钥部分验证,并逐条解释声明。

100% 本地运行——密钥和令牌都在你的浏览器中创建和使用,不会发送到任何服务器

算法和密钥

PEM(PKCS #8、SEC 1、PKCS #1)、JWK 或 OpenSSH 私钥
令牌的编写方式

头部

留空则省略 typ
内容类型,用于嵌套令牌
JSON 对象,最后合并;alg 始终为所选算法

声明

多个受众:每行一个,或用逗号分隔
15m、2h、7d、-30s 或秒数
JSON 对象;同一声明重复设置时,以上方字段为准

示例:RFC 7515 附录 A.1——JWS 规范中公布的 HS256 令牌和测试密钥。

粘贴密钥即可签名令牌。头部和声明的预览显示在下方。

What gets signed

A JWT (RFC 7519) is a JSON object of claims carried as the payload of a JWS (RFC 7515). In the compact form you see in an Authorization: Bearer header it has three parts separated by dots: the protected header, the payload and the signature, each encoded as base64url without padding.

The signature does not cover the JSON as a data structure. It covers the exact ASCII bytes of BASE64URL(header) + "." + BASE64URL(payload) — the signing input (RFC 7515 §5.1). Reordering two members or adding a space changes the bytes, so it changes the token; that is why the signer shows the signing input next to the result, and why its Exact JSON mode signs your header and claims precisely as typed. With that mode the page reproduces the HS256 example of RFC 7515 Appendix A.1 byte for byte — the example you can load above.

Algorithms and the keys they need

The header's alg names the algorithm, from the registry of RFC 7518 and its extensions. Each algorithm takes exactly one kind of key:

algAlgorithmKeyNotes
HS256, HS384, HS512HMAC with SHA-2shared secretat least as long as the hash output: 32 bytes for HS256 (RFC 7518 §3.2)
RS256, RS384, RS512RSASSA-PKCS1-v1_5RSA private key2048 bits or more (RFC 7518 §3.3); deterministic
PS256, PS384, PS512RSASSA-PSSRSA private keyrandomized: every token differs
ES256, ES384, ES512ECDSA on P-256, P-384, P-521EC private key on that curvesignature is raw R‖S — 64, 96 or 132 bytes — not DER (RFC 7518 §3.4)
ES256KECDSA on secp256k1secp256k1 private keyRFC 8812
Ed25519, Ed448, EdDSAEdDSAOKP private keyRFC 8037; RFC 9864 replaces the polymorphic EdDSA with Ed25519 and Ed448

The signer reads the key in every common form — PEM (PKCS #8, SEC 1, PKCS #1), a JWK or an OpenSSH private key — and refuses a key that does not fit the algorithm: a P-384 key for ES256, an X25519 key for EdDSA, RSA below 2048 bits. For HMAC the secret can be text or bytes written as hex or base64, or a JWK with kty oct. If you paste the text of a public key or certificate as an HMAC secret, the token is still produced, because that is how you test a verifier against algorithm confusion (RFC 8725 §2.1) — and the page says so in plain words. ES256 vs RS256 compares the two most common choices.

Claims and time

Registered claims follow RFC 7519 §4.1. iss, sub and jti are strings; aud is a string or, with several audiences, an array. The time claims iat, nbf and exp are NumericDate values: seconds since 1970-01-01T00:00:00Z (RFC 7519 §2). The signer turns relative times such as 15m, 2h or -30s into those seconds at the moment it signs, accepts ISO 8601 dates with an explicit time zone, and refuses a 13-digit value, because a millisecond timestamp is the classic mistake that makes a token expire thousands of years from now.

Before signing, every claim is checked the way a verifier will check it: a token without exp, already expired, valid for over a year, issued in the future, or never valid because nbf is not before exp is flagged with the reason. The header's typ defaults to JWT; set it to a specific type such as at+jwt to make tokens of different kinds impossible to confuse (RFC 8725 §3.11).

Key IDs and certificates

A verifier with several keys picks one by the header's kid. The signer can set it to the key's RFC 7638 thumbprint — a SHA-256 hash of the public key's required members — so the same key always gets the same ID; the JWKS builder uses the same value when it publishes the public key. With a certificate, the header can carry x5t#S256, x5t and the chain itself in x5c (RFC 7515 §4.1.6–4.1.8); the signer first checks that the certificate holds the public half of your signing key and warns when it has expired.

What runs where

Everything happens in your browser: parsing the key, building the header and claims, signing with the Web Crypto API through jose, or with @noble/curves for ES256K and Ed448, and verifying the new token with the public half of the key — for HMAC, the same secret — before it is shown. A token the page cannot verify itself is never handed out. The page makes no request with what you type, and share links carry the algorithm, header and claims — never the key or the secret.

alg none produces an unsecured token (RFC 7519 §6) with an empty signature part. It is offered for one purpose: to confirm that your verifier rejects it. RFC 8725 §3.1 requires libraries to let the caller name the algorithms it accepts and to use no others, so a verifier configured for ES256 must refuse such a token.