首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >IDX10503:签名验证失败。托肯没有孩子。键试过:“System.Text.StringBuilder”

IDX10503:签名验证失败。托肯没有孩子。键试过:“System.Text.StringBuilder”
EN

Stack Overflow用户
提问于 2021-05-23 20:01:12
回答 3查看 18.5K关注 0票数 9

我有下面的JWT令牌,

代码语言:javascript
运行
复制
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnRpZCIsImF1ZCI6ImNsaWVudGlkIiwic3ViIjoiMTIzIiwiYSI6IjQ1NiIsImlhdCI6MTYyMTc5OTU5OCwiZXhwIjoxNjIxNzk5NjU4fQ.hglbX63zhPwTOsB-zSiOMfxEKl5OaIk6zX1o9-LEhP3nro8fa5_3QyIH7I5971j-xuO1bccX1TOh0kNcQ-ACAg

它是用

代码语言:javascript
运行
复制
    public static string GenerateToken(string key, string a1, string a2)
    {
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var token = new JwtSecurityToken(
            claims: new Claim[]
            {
            new Claim(JwtRegisteredClaimNames.Iss, "clientid"),
            new Claim(JwtRegisteredClaimNames.Aud, "clientid"),
            new Claim(JwtRegisteredClaimNames.Sub, a1),
            new Claim("a", a2),
            new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),
            },
            //notBefore: new DateTimeOffset(DateTime.Now).DateTime,
            expires: new DateTimeOffset(DateTime.Now.AddMinutes(1)).DateTime,
            signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha512)
        );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

var key = "Ym7AD3OT2kpuIRcVAXCweYhV64B0Oi9ETAO6XRbqB8LDL3tF4bMk9x/59PljcGbP5v38BSzCjD1VTwuO6iWA8uzDVAjw2fMNfcT2/LyRlMOsynblo3envlivtgHnKkZj6HqRrG5ltgwy5NsCQ7WwwYPkldhLTF+wUYAnq28+QnU=";
// Key is test                
var token = GenerateToken(key, "123", "456");

获得令牌后,我将使用下面的代码进行验证,

代码语言:javascript
运行
复制
var key = "Ym7AD3OT2kpuIRcVAXCweYhV64B0Oi9ETAO6XRbqB8LDL3tF4bMk9x/59PljcGbP5v38BSzCjD1VTwuO6iWA8uzDVAjw2fMNfcT2/LyRlMOsynblo3envlivtgHnKkZj6HqRrG5ltgwy5NsCQ7WwwYPkldhLTF+wUYAnq28+QnU=";
// key is test

var hmac = new HMACSHA512(Convert.FromBase64String(key));
var validationParameters = new TokenValidationParameters
            {
                ValidAudience = "clientid",
                ValidIssuer = "clientid",
                IssuerSigningKey = new SymmetricSecurityKey(hmac.Key)
            };
            var tokenHandler = new JwtSecurityTokenHandler();
            return tokenHandler.ValidateToken(token, validationParameters, out var validToken);

但我的错误越来越少,

代码语言:javascript
运行
复制
IDX10503: Signature validation failed. Token does not have a kid. Keys tried: 'System.Text.StringBuilder'.
Exceptions caught:
 'System.Text.StringBuilder'.
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-05-24 10:16:32

问题是这条线,

代码语言:javascript
运行
复制
var hmac = new HMACSHA512(Convert.FromBase64String(key));

我把它改了,

代码语言:javascript
运行
复制
var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(key));

这个错误是误导性的。错误的源代码位于https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/d6f2b66d788195b50f2b1f700beb497851194c73/src/System.IdentityModel.Tokens.Jwt/JwtSecurityTokenHandler.cs#L1016

票数 10
EN

Stack Overflow用户

发布于 2022-03-26 03:11:22

除了能够使用上面演示的base64编码的键值之外,还可以使用字符串。不过,也有一些警告。

使用SymmetricSecurityKey创建HMACSHA256或HMACSHA512的处理程序不执行散列大小(根据RFC2104,步骤1)的零位填充,这会导致签名算法失败。如果用作键的字符串大于键大小(256或512位),则一切正常工作。

下面是为较短签名字符串生成适当SymmetricSecurityKey的两种方法:

第一种方法:手动将字符串填充为零字节,并生成base64键。类似CyberChef的内容可以用于将/0字符追加到32个字符( 256位)或64个字符( 512位):

通过base64手动生成CyberChef密钥

这些密钥将产生相同的JWT。

JWT.io中的等效密钥

如上面Imran所示.

代码语言:javascript
运行
复制
// Set up the signingKey for HS256
// Base64 signingKey
//SymmetricSecurityKey signingKey = new SymmetricSecurityKey(Convert.FromBase64String("c2VjcmV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));

第二种方法:不执行base64转换的,只要您已经完成了填充,SymmetricSecurityKey就会使用ascii byte[]:

代码语言:javascript
运行
复制
// Short String signingKey
// Note: Not advised. Short keys can be bruteforced, allowing tokens to be forged. 
// Note: manually padding to 256 bits if it is a short key, as the SymmetricSignatureProvider does not do the HMACSHA256 RFC2104 padding for you.
// SymmetricSecurityKey signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("secret".PadRight((256/8), '\0')));
SymmetricSecurityKey signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("secret".PadRight((512/8), '\0')));

无论采用哪种方法,都可以在默认的SymmetricSecurityKey处理程序中使用生成的JwtBearer:

代码语言:javascript
运行
复制
builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = true,
        ValidateIssuer = true,
        ValidIssuer = "https://localhost:7046/",
        ValidAudience = "https://localhost:7046/",
        RequireSignedTokens = true,
        IssuerSigningKey = signingKey,
        ValidateLifetime = true
    };
});

builder.Services.AddAuthorization(auth =>
            {
                auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
                    .RequireAuthenticatedUser().Build());
            });

最后,我在一个测试中遇到了一些问题,我在测试中添加了Microsoft.IdentityModel.Tokens包。我还得把这个说清楚,但是那个包里可能有个相互矛盾的类.

这里有一个使用以下方法的示例:GitHub中的示例项目

值得注意的是,不建议为HMAC使用一个短的对称密钥,因为秘密可以相对容易地被强暴,特别是如果它出现在已知的密码列表中。值得检查您的密钥过去的HaveIBeenPwned - PwnedPasswords有一些信心,它是否曾经使用过。这主要是为创建短HMAC演示的人提供的。如果您对使用PwnedPasswords感到不舒服,请参阅有关他们使用的K-匿名模型的以下内容,并在浏览器工具中查看您的网络选项卡时进行实验,以了解其工作原理。

票数 5
EN

Stack Overflow用户

发布于 2022-01-24 22:20:47

我收到同样的错误消息,但我的问题不一样。问题在于这一行:

代码语言:javascript
运行
复制
new Ed25519PublicKeyParameters(Encoding.UTF8.GetBytes(key), 0);

所以我换个说法:

代码语言:javascript
运行
复制
new Ed25519PublicKeyParameters(Convert.FromBase64String(key), 0);

Key被保存为base64文件,但我以UTF8字节的形式加载它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67663848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档