使用Azure Key Vault签名JWT Token失败问题求助
解决Azure Key Vault签名JWT验证失败的问题
我帮你定位到了两个关键错误,这就是为什么你的Key Vault签名JWT无法通过验证的原因:
1. 字符编码不符合JWT规范
你在处理签名数据时使用了Encoding.Unicode.GetBytes(headerAndPayload),但JWT标准明确要求所有字符串必须以UTF-8编码转换为字节流。Unicode本质是UTF-16,会生成完全不同的字节序列,导致哈希值和预期不符,签名自然无法通过验证。
2. 重复计算哈希值导致签名逻辑错误
Azure Key Vault的SignAsync方法在使用RS256算法时,会自动对输入数据执行SHA256哈希计算,再进行RSA签名。而你手动提前计算了哈希值并传给该方法,相当于让Key Vault对「哈希的哈希」进行签名,这完全违背了JWT的标准签名流程,最终导致签名无效。
修正后的完整代码
var handler = new JwtSecurityTokenHandler(); var expiryTime = DateTimeOffset.UtcNow.AddMinutes(10).ToUnixTimeSeconds(); var claims = new[] { new Claim(JwtRegisteredClaimNames.Iss, clientId), new Claim(JwtRegisteredClaimNames.Sub, integrationUser), new Claim(JwtRegisteredClaimNames.Aud, "https://test.example.com"), new Claim(JwtRegisteredClaimNames.Exp, expiryTime.ToString()), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) // 防重放攻击的JTI }; var header = @"{""alg"":""RS256"",""typ"":""JWT""}"; var payload = JsonConvert.SerializeObject(new JwtPayload(claims)); var headerAndPayload = $"{Base64UrlEncoder.Encode(header)}.{Base64UrlEncoder.Encode(payload)}"; // 修正:使用UTF-8编码获取字节流,无需手动计算哈希 var dataToSign = Encoding.UTF8.GetBytes(headerAndPayload); var credential = new InteractiveBrowserCredential(); var client = new KeyClient(vaultUri: new Uri(kvUri), credential); // 建议使用异步方法,符合Azure SDK最佳实践 var keyResponse = await client.GetKeyAsync("dan-test"); var cryptoClient = new CryptographyClient(keyResponse.Value.Id, credential); // 直接传入原始数据,Key Vault会自动处理SHA256哈希和RSA签名 var signatureResult = await cryptoClient.SignAsync(SignatureAlgorithm.RS256, dataToSign); var token = $"{headerAndPayload}.{Base64UrlEncoder.Encode(signatureResult.Signature)}";
修正后生成的JWT完全符合JWT标准签名流程,你可以在jwt.io上粘贴Key Vault对应的公钥进行验证,也能正常调用目标API了。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

