Сообщение об ошибке
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.
Почему это происходит
Короткий секрет в конфигурации
частоВ руководствах используют значения вроде `MySecretKey12345` или `supersecret`. В UTF-8 они занимают намного меньше 32 байт.
Обновление Microsoft.IdentityModel с ранних 6.x
частоРелизы как минимум до 6.8.0 подписывали 128-битными ключами HMAC; текущие 6.x, 7.x и 8.x требуют минимума из RFC, поэтому обновление (часто подтягиваемое вместе с обновлением ASP.NET Core) ломает приложения с короткими секретами.
HS512 с ключом, рассчитанным на HS256
иногда32-байтового ключа достаточно для HS256, но не для HS512, которому нужно 64 байта.
Как исправить
- 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.
Декодируйте его в байты
Стройте ключ из декодированных байтов, чтобы использовалась вся энтропия и каждый сервис получал один и тот же ключ.
csharp var keyBytes = Convert.FromBase64String(builder.Configuration["Jwt:KeyBase64"]!); var signingKey = new SymmetricSecurityKey(keyBytes); // 64 bytes