Перейти к содержимому
ecdsa.com
jose (JavaScript)Библиотеки JWT

Сообщение об ошибке

signature verification failed

jose (JavaScript) — JWSSignatureVerificationFailed, code ERR_JWS_SIGNATURE_VERIFICATION_FAILED

Что это означает

jose успешно разобрала JWS и выполнила криптографическую проверку, но подпись не проходит проверку выбранным ключом. Структура, алгоритм и тип ключа были допустимы — просто не сошлась математика, а это указывает на ключ или на изменённые подписанные байты.

Почему это происходит

Как исправить

  1. 1.

    Выбирайте ключи по kid из JWKS издателя

    Пусть jose сама выбирает подходящий ключ для каждого токена вместо закрепления одного ключа вручную; createRemoteJWKSet кеширует ключи и обновляет их при ротациях.

    js
    import { createRemoteJWKSet, jwtVerify } from "jose";
    
    const jwks = createRemoteJWKSet(new URL("https://issuer.example/.well-known/jwks.json"));
    const { payload } = await jwtVerify(token, jwks, {
      algorithms: ["ES256"],
      issuer: "https://issuer.example",
    });
  2. 2.

    Если подписываете через node:crypto, выдавайте подпись в формате raw r‖s

    В собственном коде подписи запрашивайте вывод в формате IEEE P1363, чтобы подпись была в 64-байтном формате, которого требует JWS, — или проверяйте результат своего кода подписи по длине третьего сегмента.

    js
    import { sign } from "node:crypto";
    
    const sig = sign("sha256", Buffer.from(signingInput), {
      key: privateKey,
      dsaEncoding: "ieee-p1363", // raw r||s, 64 bytes for P-256
    });
  3. 3.

    Проверьте, как выглядит сегмент подписи

    Декодируйте третий сегмент токена: 64 байта означают raw r‖s (правильно для ES256), а ~70 байт, начинающихся с 0x30, — DER. Конвертер DER ⇄ raw ниже показывает значения r и s и преобразует подпись из одного формата в другой.

Связанные ошибки

Открыть всю базу ошибок подписей