C# 如何加密JWT安全令牌?
我需要用签名和加密保护我的web令牌。我写了下面几行代码:C# 如何加密JWT安全令牌?,c#,security,wif,jwt,C#,Security,Wif,Jwt,我需要用签名和加密保护我的web令牌。我写了下面几行代码: var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, owner.Name),
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, owner.Name),
new Claim(ClaimTypes.Role, owner.RoleClaimType),
new Claim("custom claim type", "custom content")
}),
TokenIssuerName = "self",
AppliesToAddress = "http://www.example.com",
Lifetime = new Lifetime(now, now.AddSeconds(60 * 3)),
EncryptingCredentials = new X509EncryptingCredentials(new X509Certificate2(cert)),
SigningCredentials = new X509SigningCredentials(cert1)
};
var token = (JwtSecurityToken)tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
因此,我正在使用一些证书,这些证书是由makecert.exe
生成的。然后我用另一个JwtSecurityTokenHandler
读取令牌字符串:
var tokenHandlerDecr = new JwtSecurityTokenHandler();
var tok = tokenHandlerDecr.ReadToken(tokenString);
而且令牌内容没有加密(我可以在调试器下的
tok
变量中看到json)。我做错了什么?如何加密令牌数据?我的理解是,Microsoft的JWT实现目前不支持加密(仅支持签名)。我知道这是一篇老文章,但我正在添加我的答案,以防有人仍在搜索答案
这一问题在本报告中得到了解决。
CreateJwtSecurityToken
函数中有一个重载方法,它接受加密凭据来加密令牌
如果接收者不验证签名,并尝试按原样读取JWT,则声明为空。以下是代码片段:
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
const string sec = "ProEMLh5e_qnzdNUQrqdHPgp";
const string sec1 = "ProEMLh5e_qnzdNU";
var securityKey = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec));
var securityKey1 = new SymmetricSecurityKey(Encoding.Default.GetBytes(sec1));
var signingCredentials = new SigningCredentials(
securityKey,
SecurityAlgorithms.HmacSha512);
List<Claim> claims = new List<Claim>()
{
new Claim("sub", "test"),
};
var ep = new EncryptingCredentials(
securityKey1,
SecurityAlgorithms.Aes128KW,
SecurityAlgorithms.Aes128CbcHmacSha256);
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.CreateJwtSecurityToken(
"issuer",
"Audience",
new ClaimsIdentity(claims),
DateTime.Now,
DateTime.Now.AddHours(1),
DateTime.Now,
signingCredentials,
ep);
string tokenString = handler.WriteToken(jwtSecurityToken);
// Id someone tries to view the JWT without validating/decrypting the token,
// then no claims are retrieved and the token is safe guarded.
var jwt = new JwtSecurityToken(tokenString);
试试下面的例子 于2019年7月更新:.NET核心、Asp.NET核心 1.创建JWT
private string CreateJwt(string sub, string jti, string issuer, string audience)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, sub),
new Claim(JwtRegisteredClaimNames.Jti, jti),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var encryptingCredentials = new EncryptingCredentials(key, JwtConstants.DirectKeyUseAlg, SecurityAlgorithms.Aes256CbcHmacSha512);
var jwtSecurityToken = new JwtSecurityTokenHandler().CreateJwtSecurityToken(
issuer,
audience,
new ClaimsIdentity(claims),
null,
expires: DateTime.UtcNow.AddMinutes(5),
null,
signingCredentials: creds,
encryptingCredentials: encryptingCredentials
);
var encryptedJWT = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
return encryptedJWT;
}
2.添加到Startup.cs
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Issuer"),
ValidAudience = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Audience"),
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
TokenDecryptionKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
ClockSkew = TimeSpan.FromMinutes(0),
};
});
如果是这样的话,如果你能提供一些关于这个主题的链接,我将不胜感激。我已经探索了这个扩展,看起来你是对的-加密还不受支持。谢谢仍然是这样吗?我们还有其他方法来实现这个功能吗?任何可以使用或可能覆盖JwtSecurityTokenHandler的库?此问题在Microsoft.IdentityModel.Tokens版本5.1.3中解决。有关详细信息,请参阅我的答案。由于在验证令牌时没有传递密钥的选项,因此我是否会解密令牌?@SangSuantak TokenValidationParameters具有TokenDecryptionKey属性。验证程序在内部使用此属性解密令牌。我已经更新了我的答案,包括解密part@Amey我们可以使用公钥-私钥对来加密和解密JWT令牌吗。如果是,如何。。您有最新的示例吗?@JacobStamm该页面如何说明
IdentityModel
已被弃用?只有WCF不推荐使用。WIF不是。您能分析并帮助我从请求接收令牌的代码,然后解码并与存储的数据令牌进行比较吗?这段代码运行良好,但我不明白它是如何工作的,谢谢!
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Issuer"),
ValidAudience = (string)Configuration.GetSection("JwtToken").GetValue(typeof(string), "Audience"),
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
TokenDecryptionKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecretKeySecretKeySecretKeySecretKeySecretKeySecretKeySecretKeyS")),
ClockSkew = TimeSpan.FromMinutes(0),
};
});