Test tokens

The ways a token can be wrong

Anyone can sign a token. The useful part is a curated set of ways to break one, each with the outcome your service should reach and an explanation a security reviewer will accept. No account needed to read these.

If a term below is unfamiliar, the glossary explains the vocabulary these cases are written in, and the guides cover why they are worth testing at more length than this list allows.

Search
Kind
Expected

alg-none

JWTNEGvulnerabilityCVE-2015-9235

A token declaring alg none and carrying no signature at all. A service that accepts it can be forged by anyone who can type. CWE-347.

expired

JWTNEGnormativeRFC 7519 §4.1.4

A correctly signed token whose exp claim is in the past. A service that accepts it is not checking expiry, so any leaked token works forever.

not-yet-valid

JWTNEGnormativeRFC 7519 §4.1.5

A correctly signed token whose nbf claim is in the future. Usually a clock difference between two machines rather than an attack.

signature-stripped

JWTNEGvulnerabilityRFC 7515 §5.2

A token that claims to be signed, with the signature deleted. A service treating an absent signature as nothing to check can be forged. CWE-347.

tampered-payload

JWTNEGvulnerabilityRFC 7515 §5.2

A correctly signed token whose contents were changed afterwards. The signature no longer matches the claims, which is what signing exists to catch. CWE-345.

unknown-kid

JWTNEGhardeningRFC 7515 §4.1.4

A token signed with the real key but pointing at a key id that is not published. A service that tries every key until one works is guessing. CWE-347.

valid

JWTPOSnormativeRFC 7515 §5.2

A correctly signed token, and the control case: if your service rejects this one, the failure cases below will not tell you much.

wrong-key

JWTNEGvulnerabilityRFC 7515 §5.2

A properly signed token, signed with a key your service should not trust. Checks whether it verifies which key signed, or only that something did. CWE-347.

wycheproof-jws-alg-is-none

JWSNEGvulnerabilityRFC 7515

Algorithm none must not be accepted by default.

wycheproof-jws-json-serialization

JWSNEGnormativeRFC 7515

The JWE/JWS is encoded with JSON serialization instead of compact serialization.

wycheproof-jws-modified-padding

JWSNEGnormativeRFC 7515

The PKCS #1 padding of the signature has been modified.

wycheproof-jws-modified-signature

JWSNEGnormativeRFC 7515

The signature has been modified.

wycheproof-jws-wrong-primitive

JWSNEGnormativeRFC 7515

The signature uses a different algorithm than the algorithm specified in the key.

wycheproof-jwe-compressed-plaintext

JWEPOSnormativeRFC 7516

The plaintext in this test vector has been compressed.

wycheproof-jwe-json-serialization

JWENEGnormativeRFC 7516

The JWE/JWS is encoded with JSON serialization instead of compact serialization.

wycheproof-jwe-modified-pkcs15-padding

JWENEGnormativeRFC 7516

The PKCS #1 padding has been modified. Padding errors should not be distinguishable.

wycheproof-jwe-pkcs15-with-oaep-key

JWENEGnormativeRFC 7516

The private key is an RSA-OAEP key, but the encryption uses PKCS #1.5 padding

wycheproof-jwe-wrong-cipher

JWENEGnormativeRFC 7516

A key was used with the wrong cryptographic primitive.

wycheproof-jwk-ambiguous

JWKNEGhardeningRFC 7517

Marks test vectors with behavior that is not well defined by the RFCs. Best practice is to reject such cases.

wycheproof-jwk-duplicate-kid

JWKNEGvulnerabilityRFC 7517

The keyset contains multiple keys with the same kid. The test expects that such keysets are rejected.

wycheproof-jwk-mixed-key-set

JWKNEGvulnerabilityRFC 7517

The keyset contains public and private keys. The test expects that such keysets are rejected.

wycheproof-aes-cbc-hmac-ktv

JOSEPOSnormativeRFC 7518 §5.2

Test vector from RFC 7518.

wycheproof-aes-cbc-hmac-modified-tag

JOSENEGvulnerabilityRFC 7518 §5.2

The test vector contains a ciphertext with a modified tag. The test vector was obtained by manipulating a valid ciphertext. The purpose of the test is to check whether the verification fully checks the tag.

wycheproof-aes-cbc-hmac-pseudorandom

JOSEPOSnormativeRFC 7518 §5.2

The test vector contains pseudorandomly generated inputs. The goal of the test vector is to check the correctness of the implementation for various sizes of the input parameters. Some libraries do not support all the parameter sizes. In particular the size of the IV is often restricted.

wycheproof-aes-cbc-hmac-special-case-iv

JOSEPOSnormativeRFC 7518 §5.2

Special case iv

wycheproof-jose-json-serialization

JOSENEGnormativeRFC 7515

The JWE/JWS is encoded with JSON serialization instead of compact serialization.

wycheproof-jose-json-web-keyset

JOSENEGnormativeRFC 7515

The provided keys are actually JSON Web Keysets instead of single JSON Web Keys.

wycheproof-aes-eax-counter-wrap

AES-EAXPOSnormativeEAX mode

AES-EAX reduces the counter value modulo 2^128. This test vector was constructed for testing the wrapping of the counter value.

wycheproof-aes-eax-cve-2017-18330

AES-EAXPOSvulnerabilityCVE-2017-18330

Overflow with large IVs

wycheproof-aes-eax-ktv

AES-EAXPOSnormativeEAX mode

Known test vector from eprint.iacr.org/2003/069

wycheproof-aes-eax-modified-tag

AES-EAXNEGvulnerabilityEAX mode

The test vector contains a ciphertext with a modified tag. The test vector was obtained by manipulating a valid ciphertext. The purpose of the test is to check whether the verification fully checks the tag.

wycheproof-aes-eax-pseudorandom

AES-EAXPOSnormativeEAX mode

The test vector contains pseudorandomly generated inputs. The goal of the test vector is to check the correctness of the implementation for various sizes of the input parameters.

wycheproof-aes-eax-small-iv

AES-EAXPOShardeningEAX mode

AES-EAX allows arbitrary sizes for the nonce. This test vector uses an IV smaller than 12 bytes.

wycheproof-aes-gcm-counter-wrap

AES-GCMPOSvulnerabilityNIST SP 800-38D

The counter for GCM is reduced modulo 2**32. This test vector contains values such that the GCM counter wraps around.

wycheproof-aes-gcm-ktv

AES-GCMPOSnormativeNIST SP 800-38D

Known test vector.

wycheproof-aes-gcm-long-iv

AES-GCMPOSnormativeNIST SP 800-38D

GCM allows long IVs. Such IVs are compressed using GHASH to generate the CTR values. Some implementations restrict the range of the IV sizes.

wycheproof-aes-gcm-modified-tag

AES-GCMNEGvulnerabilityNIST SP 800-38D

The test vector contains a ciphertext with a modified tag. The test vector was obtained by manipulating a valid ciphertext. The purpose of the test is to check whether the verification fully checks the tag.

wycheproof-aes-gcm-pseudorandom

AES-GCMPOSnormativeNIST SP 800-38D

The test vector contains pseudorandomly generated inputs. The goal of the test vector is to check the correctness of the implementation for various sizes of the input parameters. Some libraries do not support all the parameter sizes. In particular the size of the IV is often restricted.

wycheproof-aes-gcm-small-iv

AES-GCMPOShardeningNIST SP 800-38D

GCM leaks the authentication key if the same IV is used twice. Hence short IV sizes are typically discouraged or generated with a special construction such as the one described in Section 8.2 of NIST SP 800-38d. Some libraries may reject small IV sizes.

wycheproof-aes-gcm-special-case

AES-GCMPOSnormativeNIST SP 800-38D

The test vector contains special cases for iv and tag.

Showing the first 40 of 240 matching cases. Narrow the search to see the rest.

Reference

URL or embedded key?

Your app needs the public key to check a token. It can fetch it from a URL at runtime, or carry it as a file. Both are normal. The trade is always the same one: who controls rotation.

Fetch from the URLEmbed the key
RotationAutomatic on next fetchNeeds a redeploy
NetworkDepends on the URLNone
TrustWhatever the endpoint servesPinned to one key
SuitsA signer that rotates keysOffline, air-gapped, or pinned

Use the URL when the signer rotates its keys, which is what every identity provider does. That is why it became the norm, and it is usually a one-line config change.

Embed the key when you cannot make a network call while checking a token, or when you want your app pinned to one key so a compromised endpoint could not introduce another. Export the PEM from the Keysets tab.

One catch worth knowing: Spring Boot's public-key-location only loads RSA keys. An ES256 or EdDSA key needs a custom decoder, or the URL.