【问题标题】:Ignoring signature in JWT忽略 JWT 中的签名
【发布时间】:2015-01-09 15:33:47
【问题描述】:

我有一个使用 OpenId Connect 的 Web 应用程序。我创建了一个自签名证书,但它仍未由 CA 签名。 如何忽略签名验证?

这是我目前所拥有的:

SecurityToken validatedToken = null;

var tokenHandler = new JwtSecurityTokenHandler {
    Configuration = new SecurityTokenHandlerConfiguration {
        CertificateValidator = X509CertificateValidator.None
    },
};

TokenValidationParameters validationParams =
    new TokenValidationParameters()
    {
        ValidAudience = ConfigurationManager.AppSettings["Audience"],
        ValidIssuer = ConfigurationManager.AppSettings["Issuer"],
        AudienceValidator = AudienceValidator,
        ValidateAudience = true,
        ValidateIssuer = true
    };

return tokenHandler.ValidateToken(jwtToken, validationParams, out validatedToken);

它会抛出以下异常:

IDX10500:签名验证失败。无法解决 SecurityKeyIdentifier: 'SecurityKeyIdentifier\r\n (\r\n
IsReadOnly = False,\r\n 计数 = 1,\r\n 子句[0] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause\r\n
)\r\n',\n令牌: '{\"typ\":\"JWT\",\"alg\":\"RS256\",\"kid\":\"issuer_rsaKey\"}.{\"iss\":...

【问题讨论】:

标签: c# .net x509certificate jwt


【解决方案1】:

不要忽略签名,这很危险!

即使您使用自签名证书,您也可以使用公钥进行签名验证。

由于您使用的是 OpenId Connect,因此您应该能够通过前往/.well-known/jwks 获取签名证书的公钥

然后您可以像这样设置验证参数:

var certificate = new X509Certificate2(Convert.FromBase64String(yourPublicKeyGoesHere));

var validationParameters = new TokenValidationParameters { 
    IssuerSigningTokens = new[] { new X509SecurityToken(certificate) }  
};

之后,您可以拨打ValidateToken

SecurityToken token;
var claimsPrincipal = handler.ValidateToken(encodedToken, validationParameters, out token);

您真的要忽略签名吗?

记住,如果你这样做了,你怎么知道有人没有篡改令牌内的数据?您可以轻松解码 base64 url​​ 编码的有效负载并更改主题。如果您在应用程序中依赖它,您将遇到麻烦(提示:有人访问其他人的数据

你真的,真的想忽略它吗?

您可以使用 ReadToken 并跳过所有验证:

var badJwt = new JwtSecurityTokenHandler()
                 .ReadToken(encodedMaliciousToken) as JwtSecurityToken;

不要这样做,这是不好的做法。

【讨论】:

  • 为什么将TokenValidationParameter.ValidateIssuerSigningKey设置为false并不能绕过签名验证?
  • @Veverke 查看JwtSecurityTokenHandler.cs 的源代码,它根本不尊重TokenValidationParameter.ValidateIssuerSigningKey。就令牌验证而言,它似乎没有影响.....
【解决方案2】:
public TokenValidationParameters CreateTokenValidationParameters()
{
    var result = new TokenValidationParameters
    {
        ValidateIssuer = false,
        ValidIssuer = ValidIssuer,

        ValidateAudience = false,
        ValidAudience = ValidAudience,

        ValidateIssuerSigningKey = false,
        //IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)),
        //comment this and add this line to fool the validation logic
        SignatureValidator = delegate(string token, TokenValidationParameters parameters)
        {
            var jwt = new JwtSecurityToken(token);

            return jwt;
        },

        RequireExpirationTime = true,
        ValidateLifetime = true,

        ClockSkew = TimeSpan.Zero,
    };

    result.RequireSignedTokens = false;
    enter code here
    return result;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-30
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2018-07-26
    相关资源
    最近更新 更多