使用密钥大小小于 2048 的 RSA 安全密钥创建 JWT 令牌时出错

Posted

技术标签:

【中文标题】使用密钥大小小于 2048 的 RSA 安全密钥创建 JWT 令牌时出错【英文标题】:Error Creating JWT Token using RSA Security Key with key size less than 2048 【发布时间】:2018-10-11 13:43:02 【问题描述】:

尝试在 C# Web API 应用程序中创建 JWT 令牌时遇到异常。

测试环境

平台:Windows 10 x64 和 .net 框架: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 令牌?

【问题讨论】:

是否需要使用较小尺寸的密钥?我的意思是你可以调整你的代码来生成所需大小的密钥。 @Evk 是的,是的。事实上,我正在为我的服务中的其他目的生成另一组密钥大小为 2048 的 RSA 密钥。然而,这个必须更小,以减少 CPU 计算开销,因为系统每秒负载大约 10K。 【参考方案1】:

在这种情况下对最小密钥大小的限制由SignatureProviderFactory.MinimumAsymmetricKeySizeInBitsForSigning 属性控制。不幸的是,还有一个“绝对”最小值,由只读字段SignatureProviderFactory.AbsoluteMinimumAsymmetricKeySizeInBitsForSigning控制,这个“绝对”最小值设置为2048。

您必须使用反射将该只读字段的值修改为您想要的值。之后,您可以将MinimumAsymmetricKeySizeInBitsForSigning 设置为相同的所需值。

示例代码:

var absoluteField = typeof(SignatureProviderFactory).GetField(nameof(SignatureProviderFactory.AbsoluteMinimumAsymmetricKeySizeInBitsForSigning), BindingFlags.Public | BindingFlags.Static);
absoluteField.SetValue(null, 512);
SignatureProviderFactory.MinimumAsymmetricKeySizeInBitsForSigning = 512;

之后,您的代码应该可以正常工作并接受大小为 512 及以上的任何不对称键。

【讨论】:

.net core 3.1 的任何 euivalnet 代码。在***.com/questions/60599339/…面临类似问题

以上是关于使用密钥大小小于 2048 的 RSA 安全密钥创建 JWT 令牌时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenSSL 的具有 SHA -256 密钥大小 2048 位的 RSA-OAEP

支付宝签名

RSA 密钥私有指数大小

RSA加密输出大小

联盟链系列 - RootCA颁发证书

联盟链系列 - RootCA颁发证书