跳到主要内容
ecdsa.com

PASETO 解码器与验证工具

粘贴 PASETO 令牌,查看其中携带的内容:版本和用途、声明、页脚。添加颁发者的公钥,即可验证 public 令牌的签名。

100% 本地处理——令牌和密钥都在你的浏览器中解码和验证,不会发送到任何服务器

令牌

版本.用途.载荷,可选附加 .页脚
Ed25519 公钥:PEM、JWK 或 32 字节的十六进制
参与认证,但从不出现在令牌中;必须与颁发者所用的值相同

示例:官方 PASETO 测试向量(paseto-standard/test-vectors),以及随之发布的公钥。

粘贴 PASETO 令牌即可解码。

PASETO in one paragraph

PASETO — Platform-Agnostic Security Tokens, specified at paseto-standard/paseto-spec — carries the same kind of claims as a JWT, with one design decision changed: the token does not say which algorithm protects it. A JWT's header names its alg, and a verifier that trusts the header can be talked into none or into checking an RSA signature as an HMAC (RFC 8725 §2.1). A PASETO token names a version and a purpose, and each pair fixes exactly one algorithm. There is nothing to negotiate.

Version, purpose, payload, footer

A token is three or four parts separated by dots: v4.public.<payload> or v4.public.<payload>.<footer>.

TokenProtectionAlgorithm
v4.publicsignedEd25519
v4.localencryptedXChaCha20 with a BLAKE2b MAC
v3.publicsignedECDSA on P-384 with SHA-384
v3.localencryptedAES-256-CTR with HMAC-SHA-384

Version 4 uses modern primitives; version 3 the NIST ones, for environments that require them. Versions 1 and 2 are retired: the decoder recognises them and tells you so instead of trying.

For a public token the payload is the message — usually a JSON object of claims — followed by the signature: 64 bytes for v4, 96 for v3. The claims are readable by anyone, which is why the decoder shows them at once, marked as unverified until the signature checks. For a local token the payload is a nonce, the ciphertext and an authentication tag; the decoder shows their sizes. Decrypting needs the shared key and is not offered here.

The optional footer is authenticated but not encrypted. It typically carries a key identifier, for example {"kid":"…"}, which the verifier reads to choose a key before checking the signature. An implicit assertion (versions 3 and 4) is authenticated too but never appears in the token: issuer and verifier both supply it — a tenant or a user ID, say — and the signature only checks when they agree. That is why the decoder asks for it.

How the signature is checked

PASETO never signs the base64 text of a token. It signs a pre-authentication encoding (PAE): every piece — the header v4.public., the message, the footer, the implicit assertion — prefixed with its length as a 64-bit little-endian integer, so that no two different combinations of pieces can produce the same bytes. Version 3 also puts the signer's compressed public key in front, binding the signature to the key. The decoder rebuilds this encoding and verifies with the audited @noble/curves: Ed25519 for v4, ECDSA P-384 with SHA-384 for v3.

A failed check has three usual causes: the token was changed, the footer or implicit assertion differs from what the issuer used, or the key is not the issuer's. The key must fit the version — an Ed25519 key for v4, a P-384 key for v3 — and the decoder refuses a key of the wrong kind rather than reporting a misleading "invalid". It reads keys as PEM, as a JWK, or as raw bytes in hex: 32 bytes for Ed25519, a compressed point for P-384. Need a key for testing? The key generator makes Ed25519 and P-384 key pairs, and the JWK converter changes their encoding.

Claims and time

PASETO's registered claims mirror JWT's — iss, sub, aud, exp, nbf, iat, jti — with one difference that trips up people moving between the two: times are ISO 8601 strings such as 2026-12-31T23:59:59+00:00, not seconds since 1970. After a successful verification the decoder checks exp, nbf and iat against the current time and flags values that are not ISO 8601 dates. To compare with a JWT built from the same claims, sign one in the JWT signer and open it in the JWT debugger.

What stays in your browser

Decoding and verification run on the page; nothing you paste is sent anywhere. A public token, a public key and an implicit assertion are public data, so a share link carries all three — except a key pasted as bare 32 bytes, which cannot be told apart from a private Ed25519 seed and is therefore left out; share the PEM form instead.