隐藏使用 RS256 PII 的 JWT SecurityTokenInvalidSignatureException

Posted

技术标签:

【中文标题】隐藏使用 RS256 PII 的 JWT SecurityTokenInvalidSignatureException【英文标题】:JWT SecurityTokenInvalidSignatureException using RS256 PII is hidden 【发布时间】:2018-11-08 11:13:31 【问题描述】:

请帮忙!我在使用 Microsoft 的 System.IdentityModel.Tokens.Jwt 库验证使用 RS256 签名的 JWT 令牌时遇到问题。

这个令牌在JWT.io 上验证得很好。

这是错误:

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException IDX10503:签名验证失败。尝试的键:'[PII 被隐藏]'。 捕获的异常: '[PII 被隐藏]'。 token: '[PII is hidden]'.

这是示例代码(我使用的是 LinqPad,带有 System.IdentityModel.Tokens.Jwt v5.2.2 NuGet 包)

void Main()

    var cText =
        "-----BEGIN CERTIFICATE-----\n" +
        "MIIBljCCAUACCQCIDMpqK7WfWDANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJV\n" + 
        "UzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UECgwJTHV4b3R0aWNhMRowGAYD\n" +
        "VQQLDBFMdXhvdHRpY2EgZXllY2FyZTAeFw0xODA1MjMxNTE1MjdaFw0yODA1MjAx\n" +
        "NTE1MjdaMFIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYD\n" +
        "VQQKDAlMdXhvdHRpY2ExGjAYBgNVBAsMEUx1eG90dGljYSBleWVjYXJlMFwwDQYJ\n" +
        "KoZIhvcNAQEBBQADSwAwSAJBAKuMYcirPj81WBtMituJJenF0CG/HYLcAUOtWKl1\n" +
        "HchC0dM8VRRBI/HV+nZcweXzpjhX8ySa9s7kJneP0cuJiU8CAwEAATANBgkqhkiG\n" +
        "9w0BAQsFAANBAKEM8wQwlqKgkfqnNFcbsZM0RUxS+eWR9LvycGuMN7aL9M6GOmfp\n" +
        "QmF4MH4uvkaiZenqCkhDkyi4Cy81tz453tQ=\n" +
        "-----END CERTIFICATE-----";

    var c = new X509Certificate2(Encoding.ASCII.GetBytes(cText));
    var p = new TokenValidationParameters();
    p.IssuerSigningKeyResolver = (s, securityToken, identifier, parameters)
        => new[]  new X509SecurityKey(c) ;
    var h = new JwtSecurityTokenHandler();
    var token = @"eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJuLmNoaWVmZm8iLCJleHAiOjE1MjcyMzg4ODEsImlzcyI6Imx1eCJ9.BAaYzLwokmdKqLi6zKjGIpDXd__dZxi5PUWWHS3PSLPDYAInzPbEK8o4WxunoGD7eA0qtQNaxNpzeOc3BHrd4w";
    h.ValidateToken(token, p, out SecurityToken _);

最后也很高兴知道如何删除 [PII is hidden],这样我就可以看到有关错误的更多详细信息。在 app.config 甚至 machine.config 文件中将 enableLoggingKnownPii 和 logKnownPII 设置为 true 似乎没有什么区别。

【问题讨论】:

【参考方案1】:

事实证明,X509SecurityKey 的 KeySize 长度至少需要 1024 才能进行验证。这在异常中并不明显,因为它被 [PII is hidden] 过滤器隐藏了。

添加以下行使异常文本更加有用(添加到Startup.cs 中的ConfigureServices 方法):

IdentityModelEventSource.ShowPII = true;

新的异常文本:

“System.ArgumentOutOfRangeException: IDX10631: 用于验证的“Microsoft.IdentityModel.Tokens.X509SecurityKey”不能小于“1024”位。密钥大小:'512'。

将非对称密钥的长度增加到 1024 解决了这个问题。

【讨论】:

如果您使用的是 RsaSha256,则大小不应小于 2024。否则会引发相同的错误。 嗨 Carlo,你是如何增加密钥长度的? 哦,我刚刚想通了。我需要做的就是在我的秘密中加入更多内容/文字。 只记得在部署到生产环境时回到默认的false。你不希望 ShowPII = true 在生产中。 增加非对称密钥的长度为我解决了这个问题。【参考方案2】:

您可以在appsettings.json 文件中增加您的密钥长度,如下所示。

"Jwt": 
    "Key": "pintusharmaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqweqwe",
    "Issuer": "pintusharma.com"
  

【讨论】:

以上是关于隐藏使用 RS256 PII 的 JWT SecurityTokenInvalidSignatureException的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JWT.IO 网站创建 RS256 JWT?

JWT 签名算法 HS256 与 RS256

C#RSACryptoServiceProvider - JWT RS256验证失败

节点 js JWT 令牌不是使用 RS256 算法生成的

使用 RS256 生成的 JWT 可以被 jwt.io 网站解码吗?

在 C# 中使用 RS256(非对称)验证 JWT