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

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

Key for the ES256 algorithm must be one of type CryptoKey, KeyObject, or JSON Web Key.

Также выводится как

  • Key for the RS256 algorithm must be one of type CryptoKey, KeyObject, or JSON Web Key.
  • Key for the HS256 algorithm must be one of type CryptoKey, KeyObject, JSON Web Key, or Uint8Array.

Алгоритм в тексте сообщения берётся из вашего токена (`ES256`, `RS256`, `EdDSA`…). Для алгоритмов HMAC список заканчивается словами «or Uint8Array».

jose (JavaScript) — TypeError from jwtVerify / SignJWT.sign

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

Вы передали jose значение, которое она не может использовать как ключ. Чаще всего это PEM-строка или секрет в виде обычной строки. Начиная с версии 4, jose принимает только объекты ключей: `CryptoKey` из WebCrypto, `KeyObject` из Node.js, объект JWK или (для алгоритмов HMAC) `Uint8Array`. Текстовые форматы сначала нужно импортировать: jose никогда не угадывает, что содержит строка.

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

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

  1. 1.

    Импортируйте PEM-ключи один раз при запуске

    `importSPKI` и `importPKCS8` принимают PEM-текст и алгоритм, с которым будет использоваться ключ, и возвращают `CryptoKey`, пригодный для повторного использования во всех запросах.

    js
    import { importSPKI, importPKCS8, jwtVerify } from "jose";
    
    const publicKey = await importSPKI(process.env.JWT_PUBLIC_KEY_PEM, "ES256");   // -----BEGIN PUBLIC KEY-----
    await jwtVerify(token, publicKey, { algorithms: ["ES256"] });
    
    const privateKey = await importPKCS8(process.env.JWT_PRIVATE_KEY_PEM, "ES256"); // -----BEGIN PRIVATE KEY-----
  2. 2.

    Преобразуйте секреты HMAC в байты

    Для HS256 используйте случайный секрет длиной не менее 32 байт и передавайте его как `Uint8Array`. Если секрет хранится в кодировке base64, декодируйте его в байты, а не кодируйте сам base64-текст.

    js
    import { jwtVerify } from "jose";
    
    const secret = new TextEncoder().encode(process.env.JWT_SECRET); // 32+ random bytes for HS256
    await jwtVerify(token, secret, { algorithms: ["HS256"] });
  3. 3.

    Проверяйте по набору ключей, а не по URL

    Для токенов от поставщика удостоверений передавайте функцию, которую возвращает `createRemoteJWKSet`; тогда jose выбирает ключ по `kid` для каждого токена.

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

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

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