我有下面的JWT令牌,
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjbGllbnRpZCIsImF1ZCI6ImNsaWVudGlkIiwic3ViIjoiMTIzIiwiYSI6IjQ1NiIsImlhdCI6MTYyMTc5OTU5OCwiZXhwIjoxNjIxNzk5NjU4fQ.hglbX63zhPwTOsB-zSiOMfxEKl5OaIk6zX1o9-LEhP3nro8fa5_3QyIH7I5971j-xuO1bccX1TOh0kNcQ-ACAg
它是用
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");
获得令牌后,我将使用下面的代码进行验证,
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);
但我的错误越来越少,
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'.
发布于 2021-05-24 10:16:32
问题是这条线,
var hmac = new HMACSHA512(Convert.FromBase64String(key));
我把它改了,
var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(key));
发布于 2022-03-26 03:11:22
除了能够使用上面演示的base64编码的键值之外,还可以使用字符串。不过,也有一些警告。
使用SymmetricSecurityKey创建HMACSHA256或HMACSHA512的处理程序不执行散列大小(根据RFC2104,步骤1)的零位填充,这会导致签名算法失败。如果用作键的字符串大于键大小(256或512位),则一切正常工作。
下面是为较短签名字符串生成适当SymmetricSecurityKey的两种方法:
第一种方法:手动将字符串填充为零字节,并生成base64键。类似CyberChef的内容可以用于将/0字符追加到32个字符( 256位)或64个字符( 512位):
这些密钥将产生相同的JWT。
如上面Imran所示.
// Set up the signingKey for HS256
// Base64 signingKey
//SymmetricSecurityKey signingKey = new SymmetricSecurityKey(Convert.FromBase64String("c2VjcmV0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="));
第二种方法:不执行base64转换的,只要您已经完成了填充,SymmetricSecurityKey就会使用ascii byte[]:
// 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:
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-匿名模型的以下内容,并在浏览器工具中查看您的网络选项卡时进行实验,以了解其工作原理。
发布于 2022-01-24 22:20:47
我收到同样的错误消息,但我的问题不一样。问题在于这一行:
new Ed25519PublicKeyParameters(Encoding.UTF8.GetBytes(key), 0);
所以我换个说法:
new Ed25519PublicKeyParameters(Convert.FromBase64String(key), 0);
Key被保存为base64文件,但我以UTF8字节的形式加载它。
https://stackoverflow.com/questions/67663848
复制相似问题