使用密钥大小小于 2048 的 RSA 安全密钥创建 JWT 令牌时出错
Error Creating JWT Token using RSA Security Key with key size less than 2048
我在 C# Web API 应用程序中尝试创建 JWT 令牌时遇到异常。
测试环境
- 平台:Windows 10 x64 with .net framework:4.6.1
- jwt NuGet 包:System.IdentityModel.Tokens.Jwt version: 4.0.2.206221351
这里是负责生成 RSA 密钥的代码:
public SignatureInformation CreateNewSignatureInformation(int length = 0)
{
try
{
var signatureInformation = new SignatureInformation();
var rsaProvider = new RSACryptoServiceProvider(length);
var publicKey = rsaProvider.ToXmlString(false);
signatureInformation.Public = publicKey;
var privateKey = rsaProvider.ToXmlString(true);
signatureInformation.Private = privateKey;
return signatureInformation;
}
catch (Exception)
{
return null;
}
}
这里是负责生成 JTW 令牌的代码,该令牌使用上述代码生成的 RSA 密钥对签名:
private string GenerateToken(string privateKeyInXml)
{
var cryptoServiceProvider = new RSACryptoServiceProvider();
cryptoServiceProvider.FromXmlString(privateKeyInXml);
var creds = new SigningCredentials(new RsaSecurityKey(cryptoServiceProvider),
SecurityAlgorithms.RsaSha256Signature,
SecurityAlgorithms.Sha256Digest);
var nbf = DateTime.UtcNow;
var exp = nbf.AddMinutes(10);
var jwtToken = new JwtSecurityToken("SAMPLE_ISSUER",
"SAMPLE_AUDIENCE",
null, //null is given as claims list in this sample
nbf,
exp,
creds);
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.WriteToken(jwtToken); //the exception is thrown here
return token;
}
抛出的异常是 System.ArgumentOutOfRangeException
类型,消息是:
"IDX10630: The 'System.IdentityModel.Tokens.RsaSecurityKey' for signing cannot be smaller than '2048' bits.\r\nParameter name: key.KeySize\r\nActual value was 512."
问题
如何使用密钥大小小于 2048 的 RSA 安全密钥生成 JWT 令牌?
在这种情况下,对最小密钥大小的限制由 SignatureProviderFactory.MinimumAsymmetricKeySizeInBitsForSigning
属性 控制。不幸的是,还有一个"absolute"最小值,它由只读字段SignatureProviderFactory.AbsoluteMinimumAsymmetricKeySizeInBitsForSigning
控制,而这个"absolute"最小值设置为2048。
您必须使用反射将该只读字段的值修改为您想要的值。之后,您可以将 MinimumAsymmetricKeySizeInBitsForSigning
设置为相同的所需值。
示例代码:
var absoluteField = typeof(SignatureProviderFactory).GetField(nameof(SignatureProviderFactory.AbsoluteMinimumAsymmetricKeySizeInBitsForSigning), BindingFlags.Public | BindingFlags.Static);
absoluteField.SetValue(null, 512);
SignatureProviderFactory.MinimumAsymmetricKeySizeInBitsForSigning = 512;
之后您的代码应该可以正常工作并接受任何大小为 512 及以上的非对称密钥。
我在 C# Web API 应用程序中尝试创建 JWT 令牌时遇到异常。
测试环境
- 平台:Windows 10 x64 with .net framework:4.6.1
- jwt NuGet 包:System.IdentityModel.Tokens.Jwt version: 4.0.2.206221351
这里是负责生成 RSA 密钥的代码:
public SignatureInformation CreateNewSignatureInformation(int length = 0)
{
try
{
var signatureInformation = new SignatureInformation();
var rsaProvider = new RSACryptoServiceProvider(length);
var publicKey = rsaProvider.ToXmlString(false);
signatureInformation.Public = publicKey;
var privateKey = rsaProvider.ToXmlString(true);
signatureInformation.Private = privateKey;
return signatureInformation;
}
catch (Exception)
{
return null;
}
}
这里是负责生成 JTW 令牌的代码,该令牌使用上述代码生成的 RSA 密钥对签名:
private string GenerateToken(string privateKeyInXml)
{
var cryptoServiceProvider = new RSACryptoServiceProvider();
cryptoServiceProvider.FromXmlString(privateKeyInXml);
var creds = new SigningCredentials(new RsaSecurityKey(cryptoServiceProvider),
SecurityAlgorithms.RsaSha256Signature,
SecurityAlgorithms.Sha256Digest);
var nbf = DateTime.UtcNow;
var exp = nbf.AddMinutes(10);
var jwtToken = new JwtSecurityToken("SAMPLE_ISSUER",
"SAMPLE_AUDIENCE",
null, //null is given as claims list in this sample
nbf,
exp,
creds);
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.WriteToken(jwtToken); //the exception is thrown here
return token;
}
抛出的异常是 System.ArgumentOutOfRangeException
类型,消息是:
"IDX10630: The 'System.IdentityModel.Tokens.RsaSecurityKey' for signing cannot be smaller than '2048' bits.\r\nParameter name: key.KeySize\r\nActual value was 512."
问题
如何使用密钥大小小于 2048 的 RSA 安全密钥生成 JWT 令牌?
在这种情况下,对最小密钥大小的限制由 SignatureProviderFactory.MinimumAsymmetricKeySizeInBitsForSigning
属性 控制。不幸的是,还有一个"absolute"最小值,它由只读字段SignatureProviderFactory.AbsoluteMinimumAsymmetricKeySizeInBitsForSigning
控制,而这个"absolute"最小值设置为2048。
您必须使用反射将该只读字段的值修改为您想要的值。之后,您可以将 MinimumAsymmetricKeySizeInBitsForSigning
设置为相同的所需值。
示例代码:
var absoluteField = typeof(SignatureProviderFactory).GetField(nameof(SignatureProviderFactory.AbsoluteMinimumAsymmetricKeySizeInBitsForSigning), BindingFlags.Public | BindingFlags.Static);
absoluteField.SetValue(null, 512);
SignatureProviderFactory.MinimumAsymmetricKeySizeInBitsForSigning = 512;
之后您的代码应该可以正常工作并接受任何大小为 512 及以上的非对称密钥。