- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在创建一个 Web 服务和关联的客户端,它将使用由 X509Certficates 加密的 JWT。当我使用对称 key 加密和解密 token 时,一切正常。但是,我想在生产中使用基于 X509Certficates 的加密,当我尝试其中之一时,出现以下异常:
在 .NET Core 上运行时:
Microsoft.IdentityModel.Tokens.SecurityTokenKeyWrapException:
IDX10659: UnwrapKey failed, exception from crypto operation:
'Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException:
Key does not exist'
在 .NET Framework 4.7 上运行时(注意内部异常有何不同):
Microsoft.IdentityModel.Tokens.SecurityTokenKeyWrapException:
IDX10659: UnwrapKey failed, exception from crypto operation:
'System.Security.Cryptography.CryptographicException:
Error occurred while decoding OAEP padding.'
从 SymmetricSecurityKey
切换到 X509SecurityKey
只是更改为 EncryptingCredentials
实例提供的值,所以我期待一切都只是工作。
这是我生成 token 的代码:
public string Generate(NodeEntitlements entitlements)
{
if (entitlements == null)
{
throw new ArgumentNullException(nameof(entitlements));
}
var claims = CreateClaims(entitlements);
var claimsIdentity = new ClaimsIdentity(claims);
var securityTokenDescriptor = new SecurityTokenDescriptor
{
Subject = claimsIdentity,
NotBefore = entitlements.NotBefore.UtcDateTime,
Expires = entitlements.NotAfter.UtcDateTime,
IssuedAt = DateTimeOffset.Now.UtcDateTime,
Issuer = "https://example.com",
Audience = "https://example.com",
SigningCredentials = SigningCredentials,
EncryptingCredentials = EncryptingCredentials
};
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateToken(securityTokenDescriptor);
return handler.WriteToken(token);
}
这是我验证相同 token 的代码(我已经注释掉抛出异常的行):
public VerificationResult Verify(string tokenString)
{
var validationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidAudience = "https://example.com",
ValidateIssuer = true,
ValidIssuer = "https://example.com",
ValidateLifetime = true,
RequireExpirationTime = true,
RequireSignedTokens = SigningKey != null,
ClockSkew = TimeSpan.FromSeconds(60),
IssuerSigningKey = SigningKey,
ValidateIssuerSigningKey = SigningKey != null,
TokenDecryptionKey = EncryptionKey
};
try
{
var handler = new JwtSecurityTokenHandler();
// Exception is thrown here
var principal =
handler.ValidateToken(tokenString, validationParameters, out var token);
var entitlementIdClaim = principal.FindFirst("id");
if (entitlementIdClaim == null)
{
return VerificationResult.IdentifierNotPresent;
}
return VerificationResult.Valid;
}
catch (SecurityTokenException ex)
{
Console.WriteLine(ex);
return VerificationResult.InvalidToken;
}
}
根据证书创建 EncryptingCredentials
:
public static EncryptingCredentials CreateCertificateEncryptionCredentials()
{
var certificate = FindCertificate();
var key = new X509SecurityKey(certificate);
var result = new EncryptingCredentials(
key, SecurityAlgorithms.RsaOAEP, SecurityAlgorithms.Aes256CbcHmacSha512);
return result;
}
这些方法取自 minimal repro (GitHub 链接)我从我的原始代码库中提取的;这里要发布的代码有点多,但其中大部分只是基础设施。重现完全在进程内工作,不使用 ASP.NET 中的任何内容。
我已经在三台不同的机器上,在两个不同的用户帐户下用多个不同的 X509Certficates 重现了这个问题,所以我认为我已经消除了证书作为问题的根源。签名在每个测试中从头到尾都正常工作,我认为这表明证书中的公钥和私钥都可以正确访问。
为什么仅使用 X509SecurityKey
而不是使用 SymmetricSecurityKey
解密失败?
使用 X509Certficates 加密/解密 JWT token 的正确方法是什么?或者,这个问题的解决方法是什么?
更新:简化重现异常的代码
最佳答案
尝试使用:
new RsaSecurityKey(certificate.GetRSAPrivateKey().ExportParameters(true));
代替 X509SecurityKey
。
在实现中似乎存在一个错误,它不允许 JIT 解包 RSA key 。
关于c# - 使用 X509Certficate 解密 JWT token 时出现 IDX10659 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43837944/
我正在使用 HttpClient (.NET Core3.1) 从多个来源发出获取请求。我只在构造函数中使用了一个实例,如下所示: _httpClient = new HttpClient(); _h
我是一名优秀的程序员,十分优秀!