Jay*_*y1b 5 c# cryptography rsa jwt
渗透测试建议我们更改 JWT 实现以使用非对称签名而不是对称签名,这种方法运行良好。
创建对称令牌的当前(完美工作)代码如下:(灵感最初来自如何加密 JWT 安全令牌?)
private string CreateToken(string Username)
{
//Set issued at date
DateTime issuedAt = DateTime.UtcNow;
//set the time when it expires
DateTime expires = DateTime.UtcNow.AddHours(1);
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
//create a identity and add claims to the user which we want to log in
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, Username)
});
DateTime now = DateTime.UtcNow;
SymmetricSecurityKey securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(SecurityConstants.ConstSecurityEncryptionKey));
SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
//create the jwt
JwtSecurityToken token = tokenHandler.CreateJwtSecurityToken(issuer: "issuer",
audience: "audience",
subject: claimsIdentity,
notBefore: issuedAt,
expires: expires,
signingCredentials: signingCredentials);
return tokenHandler.WriteToken(token);
}
}
Run Code Online (Sandbox Code Playgroud)
检查任何 API 调用请求的代码类似于以下内容:
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpStatusCode StatusCode;
string token;
//determine whether a jwt exists or not
if (!TryRetrieveToken(request, out token))
{
StatusCode = HttpStatusCode.Unauthorized;
//allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
return base.SendAsync(request, cancellationToken);
}
try
{
DateTime now = DateTime.UtcNow;
SymmetricSecurityKey SecurityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(SecurityConstants.ConstSecurityEncryptionKey));
SecurityToken securityToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
TokenValidationParameters validationParameters = new TokenValidationParameters()
{
ValidAudience = "audience",
ValidIssuer = "issuer",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
LifetimeValidator = this.LifetimeValidator,
IssuerSigningKey = SecurityKey
};
//extract and assign the user of the jwt
Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);
return base.SendAsync(request, cancellationToken);
}
catch (SecurityTokenValidationException e)
{
StatusCode = HttpStatusCode.Forbidden;
}
catch (Exception ex)
{
StatusCode = HttpStatusCode.Forbidden;
}
return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(StatusCode) { });
}
Run Code Online (Sandbox Code Playgroud)
我已经在网上尝试了很多示例并阅读了很多帖子,但还没有任何工作,每个示例都有很多不同的问题。我得到的关闭可能是遵循以下一些示例: RS256 vs HS256:有什么区别?
下面的一个示例似乎可以用于创建代码,但在将令牌与传入的 API 调用进行比较时,这将不起作用。
RSA _rsaa;
_rsaa = new RSACryptoServiceProvider(2048);
var r = _rsaa.ExportParameters(true);
SigningCredentials signingCredentials3a = new SigningCredentials(new RsaSecurityKey(_rsaa), SecurityAlgorithms.RsaSha256Signature);
Run Code Online (Sandbox Code Playgroud)
最后,下面的选项感觉是正确的,但得到的是“提供者的错误版本”。由于字符串中保存的加密密钥内容而导致错误。
byte[] Key256Bytes = Encoding.ASCII.GetBytes(Key256);
rsa.ImportCspBlob(Key256Bytes);
SigningCredentials signingCredentials5 = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256Signature);
Run Code Online (Sandbox Code Playgroud)
我很难让各种选项发挥作用。
Jay*_*y1b 10
找到了解决办法,将上面的转换成非对称加密,交换:
SymmetricSecurityKey securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(SecurityConstants.ConstSecurityEncryptionKey));
SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
Run Code Online (Sandbox Code Playgroud)
和
var rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(Convert.FromBase64String(SecurityConstants.ConstAsyncSecurityEncryptionKey));
SigningCredentials signingCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha512Signature);
Run Code Online (Sandbox Code Playgroud)
加密密钥是使用以下内容生成的。
var rsa = new RSACryptoServiceProvider(2048);
var key = Convert.ToBase64String(rsa.ExportCspBlob(true));
Run Code Online (Sandbox Code Playgroud)
然后在检查传入的 JWT 时:
SymmetricSecurityKey SecurityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(SecurityConstants.ConstSecurityEncryptionKey));
Run Code Online (Sandbox Code Playgroud)
和
var rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(Convert.FromBase64String(SecurityConstants.ConstAsyncSecurityEncryptionKey));
RsaSecurityKey SecurityKey = new RsaSecurityKey(rsa);
Run Code Online (Sandbox Code Playgroud)
希望对将来的人有所帮助。
| 归档时间: |
|
| 查看次数: |
2391 次 |
| 最近记录: |