Перейти к содержимому
ecdsa.com
Microsoft.IdentityModel.Tokens (.NET).NET

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

IDX10720: Unable to create KeyedHashAlgorithm for algorithm 'HS256', the key size must be greater than: '256' bits, key has '128' bits.

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

  • System.ArgumentOutOfRangeException: IDX10720: Unable to create KeyedHashAlgorithm for algorithm 'HS256', the key size must be greater than: '256' bits, key has '128' bits. (Parameter 'keyBytes')
  • IDX10653: The encryption algorithm 'HS256' requires a key size of at least '128' bits.

Алгоритм и число бит в сообщении соответствуют вашей конфигурации; несмотря на «must be greater than», ключ ровно требуемого размера принимается. Проверено на разных версиях: 6.8.0 и более ранние принимали 128-битные ключи HMAC; более поздние 6.x (6.36.0) и 7.x/8.x отклоняют их с IDX10720 (6.x добавляет ссылку на «UnsafeRelaxHmacKeySizeValidation»). Ключи короче 128 бит отклоняются раньше, с IDX10653 «The encryption algorithm 'HS256' requires a key size of at least '128' bits».

Microsoft.IdentityModel.Tokens (.NET) — ArgumentOutOfRangeException from SymmetricSignatureProvider

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

IdentityModel отказывается использовать ключ HMAC короче выхода хеш-функции алгоритма: HS256 требуется не менее 256 бит (32 байт), HS384 — 384, HS512 — 512, как того требует RFC 7518, § 3.2. У ключа в сообщении 128 бит, то есть 16 байт, — типичная длина секрета, набранного вручную в `appsettings.json`. Короткий секрет HMAC можно подобрать перебором офлайн по одному-единственному токену, после чего кто угодно сможет выпускать токены, которые примет ваш API.

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

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

  1. 1.

    Сгенерируйте случайный ключ нужного размера

    Используйте криптографически случайное значение, которое хранится в пользовательских секретах (user secrets) или хранилище секретов и никогда не попадает в систему контроля версий.

    bash
    # 64 random bytes, base64: valid for HS256, HS384 and HS512
    openssl rand -base64 64 | tr -d '\n'
    dotnet user-secrets set "Jwt:KeyBase64" "<the value above>"   # development; use a vault in production
  2. 2.

    Декодируйте его в байты

    Стройте ключ из декодированных байтов, чтобы использовалась вся энтропия и каждый сервис получал один и тот же ключ.

    csharp
    var keyBytes = Convert.FromBase64String(builder.Configuration["Jwt:KeyBase64"]!);
    var signingKey = new SymmetricSecurityKey(keyBytes); // 64 bytes

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

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