.NET 7验证Brainpool P256R1算法JWT签名遇曲线不支持问题
基于x5c证书链验证BP256R1算法JWT签名的问题与解决
编辑:问题已解决,成功通过x5c证书链的公钥完成JWT签名验证,感谢Topaco的评论提醒我重新检查数据,解决方案附在文末。
我是JWT验证领域的新手,想实现不依赖Bouncy Castle的JWT签名验证。目标JWT的头部包含x5c证书链,签名算法为bp256r1。
运行代码时抛出ArgumentException,错误信息如下:
IDX10645: Elliptical Curve not supported for curveId: 'brainpoolP256r1'
虽然错误信息很明确,但我以为Win10及以上系统是支持BP256R1算法的,不知道哪里出了问题?
以下是我最初的实现代码,预期验证结果为true,但实际报错:
public async Task<JwtSecurityToken> GetDiscoveryDocument() { //Get Token var response = await _client.GetAsync(".well-known/openid-configuration"); response.EnsureSuccessStatusCode(); //parse Token string token = await response.Content.ReadAsStringAsync(); var jwtHandler = new JwtSecurityTokenHandler(); var jwt = jwtHandler.ReadJwtToken(token); //Get SigningCert var x5cCerts = JsonSerializer.Deserialize<object[]>(jwt.Header["x5c"].ToString()); X509Certificate2 cert = new X509Certificate2(Encoding.UTF8.GetBytes(x5cCerts.First().ToString())); //Get PublicKey and Set validationParameters, ValidateSignature var ecdsa = cert.GetECDsaPublicKey(); var vaidationResult = await jwtHandler.ValidateTokenAsync(token, new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = true, IssuerSigningKey = new ECDsaSecurityKey(ecdsa), }); return jwt; }
我还尝试过直接调用VerifyData的方式,但也没解决问题:
var ecdsa = cert.GetECDsaPublicKey(); byte[] data = ....; byte[] signature = ....; ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA256);
解决方案
最终通过直接构造验证数据并调用ECDsa的VerifyData方法完成了签名验证,修改后的代码如下:
public async Task<JwtSecurityToken> GetDiscoveryDocument() { //Get Token var response = await _client.GetAsync(".well-known/openid-configuration"); response.EnsureSuccessStatusCode(); //parse Token string token = await response.Content.ReadAsStringAsync(); var jwtHandler = new JwtSecurityTokenHandler(); var jwt = jwtHandler.ReadJwtToken(token); //Get SigningCert var x5cCerts = JsonSerializer.Deserialize<object[]>(jwt.Header["x5c"].ToString()); X509Certificate2 cert = new X509Certificate2(Encoding.UTF8.GetBytes(x5cCerts.First().ToString())); //Get PublicKey and Set validationParameters, ValidateSignature var ecdsa = cert.GetECDsaPublicKey(); var valid = ecdsa.VerifyData(Encoding.UTF8.GetBytes(jwt.EncodedHeader + "." + jwt.EncodedPayload), Base64UrlEncoder.DecodeBytes(jwt.RawSignature), HashAlgorithmName.SHA256); return jwt; }
内容的提问来源于stack exchange,提问作者Taylingo84
相关产品推荐
相关产品推荐

