【问题标题】:JWT Header algorithm: is "hs256" the same as "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"JWT Header算法:是“hs256”与“http://www.w3.org/2001/04/xmldsig-more#hmac-sha256”相同
【发布时间】:2021-01-22 10:11:57
【问题描述】:

我正在尝试使用 HS256 签署 JWT。我正在使用 System.IdentityModel.Tokens.Jwt 。使用 jwt.io 解码令牌时,我得到 invalid signature 并且我注意到我的标头显示为:

{
  "alg": "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
  "typ": "JWT"
}

而不是我预期的{"alg":"HS256","typ":"JWT"}

这是导致无效签名的原因吗?还有关于修复的任何想法吗?请注意,我还需要包含自定义声明。

var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(clientsecret));
var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
var header = new JwtHeader(credentials);

【问题讨论】:

  • 您的签名在 jwt.io 上被认为无效的原因通常是因为您没有将密钥粘贴到右栏中“验证签名”下的字段中。 HS256hmac-sha256 的简称,不知道怎么改,会不会引起其他问题。
  • 感谢您的评论,我相信更改右侧的字段会更改左侧的编码字符串,因此会对其进行固有的验证。
  • @当秘密与用于签名的秘密不匹配时,这是真的(然后验证毫无价值)。您需要先粘贴秘密,然后将令牌粘贴到左侧,以查看是否可以使用给定的秘密验证现有令牌。
  • 嗯,是的,是有道理的。谢谢

标签: c# .net jwt jwt-auth


【解决方案1】:

SecurityAlgorithms.HmacSha256Signature

改变

SecurityAlgorithms.HmacSha256

【讨论】:

【解决方案2】:

您可以使用 System.IdentityModel.Tokens.Jwt 创建您的 JSON Web 令牌 (JWT),如下所示,它应该正确设置所有字段(secret 是您用来签署 JWT 的密钥):

var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
  Subject = new ClaimsIdentity(new[] { new Claim("sub", "customer") }),
  Issuer = "Who issued the token",
  Claims = new Dictionary<string, object>
  {
    ["email"] = Email, 
  },
  IssuedAt = now,
  NotBefore = now,
  Expires = now + TimeSpan.FromDays(1),
  SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secret), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
var serializedToken = tokenHandler.WriteToken(token);

serializedToken 终于包含了序列化的 JWT。

请注意,SecurityTokenDescriptorclass 来自same NuGet package 的 Microsoft.IdentityModel.Tokens 命名空间,而不是来自 System.IdentityModel.Tokens 命名空间。

【讨论】:

  • 感谢您的回答,对不起,我应该指定我需要自定义声明,例如电子邮件,是否有将自定义声明集成到您的方法中?谢谢
  • 是的,tokenDescriptor 有一个用于自定义声明的 Claims 字典(请参阅我编辑的答案),如果您想扩展 JWT 标头,还有一个 AdditionalHeaderClaims 字典。
  • 嗨,非常感谢您的帮助 - 很遗憾,我仍然遇到问题。在行: var tokenDescriptor = new SecurityTokenDescriptor ,我得到 System.NullReferenceException: Object reference not set to an instance of an object。我错过了什么吗?
  • SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor { Claims = { ["iss"] = clientid, ["sub"] = "customer", ["iat"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), [ "jti"] = Jti, ["email"] = Email }, SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(clientsecretba), SecurityAlgorithms.HmacSha256Signature) };
  • 查看我更新的答案 - 例外是因为您需要设置字典。此外,“iss”与在我的示例中设置“Issuer”属性相同,“sub”=“Subject”和“iat”=“IssuedAt”。 Microsoft.IdentityModel.Tokens 由 ASP.NET Core 使用,但不是其中的一部分。
猜你喜欢
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2013-06-10
相关资源
最近更新 更多