错误信息
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 密钥:按照 RFC 7518 §3.2 的要求,HS256 至少需要 256 位(32 字节),HS384 需要 384 位,HS512 需要 512 位。消息中的密钥只有 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 却不够,HS512 需要 64 字节。
修复方法
- 1.
生成长度合适的随机密钥
使用密码学安全的随机值,存放在用户机密或密钥保管库中,切勿提交到源代码管理。
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