C#中使用JWK/JWKS解密JWT令牌出现IDX10609错误求助
解决方案
你遇到的IDX10609: Decryption failed. No Keys tried错误,核心原因是解密用的密钥和JWT头部携带的密钥ID(kid)没有匹配成功,库直接跳过了你的密钥没有尝试解密。你可以按照以下步骤修复:
1. 优先使用原生JsonWebKey作为解密密钥
Microsoft.IdentityModel.Tokens原生支持JsonWebKey直接作为解密密钥,你不需要手动解析RSA参数创建RSA对象,避免转换过程出错,也能保留原JWK的kid属性,直接替换密钥配置即可:
// 删掉手动创建RSAParameters、RSA、RsaSecurityKey的相关代码 validationParameters.TokenDecryptionKey = exampleJWK;
如果你一定要手动解析RSA参数创建RSA对象使用,记得给生成的RsaSecurityKey补充Kid配置,否则会因为kid不匹配被库跳过:
RsaSecurityKey rsakey = new RsaSecurityKey(rsa) { KeyId = exampleJWK.Kid };
2. 显式匹配kid避免取错密钥
如果你的JWKS包含多个密钥,不要直接取第一个密钥,按照JWT头部的kid匹配对应密钥:
var targetKid = "5BbVY7F77gz9LWE4tUjXwNFt9qhINvWBR7Pkm1ZJlEA"; JsonWebKey exampleJWK = exampleJWKS.Keys.First(k => k.Kid == targetKid);
3. 确认库版本兼容性
如果你的Microsoft.IdentityModel.JsonWebTokens版本低于6.15.0,RSA-OAEP-256算法搭配Deflate压缩(你返回的头部zip: DEF对应压缩方式)的JWT解密存在已知bug,升级到最新稳定版即可解决。
4. 简化后的可运行代码
using System; using System.Linq; using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Tokens; namespace jwtdecoder { class Program { static void Main(string[] args) { // 替换为实际的令牌和JWKS字符串 string token = "BASE64EncodedTokenGoesHere"; string jwks = "JWKSSTRINGGOESHERE"; string targetKid = "5BbVY7F77gz9LWE4tUjXwNFt9qhINvWBR7Pkm1ZJlEA"; JsonWebKeySet exampleJWKS = new JsonWebKeySet(jwks); JsonWebKey exampleJWK = exampleJWKS.Keys.First(k => k.Kid == targetKid); JsonWebTokenHandler exampleHandler = new JsonWebTokenHandler(); TokenValidationParameters validationParameters = new TokenValidationParameters { ValidateAudience = false, ValidateIssuer = false, RequireSignedTokens = false, TokenDecryptionKey = exampleJWK }; // 直接传入令牌字符串即可,不需要提前实例化JsonWebToken string clearToken = exampleHandler.DecryptToken(token, validationParameters); // 解密后可以直接读取claims var claims = exampleHandler.ReadJwtToken(clearToken).Claims; } } }
如果按照上述步骤调整后仍然解密失败,你可以手动校验JWK的私钥完整性,确认导入到IDP的公钥和你当前使用的私钥是匹配的密钥对。
内容的提问来源于stack exchange,提问作者Johnnie Odom
相关产品推荐
相关产品推荐

