覆盖 RSA 对象中的默认算法以支持 OaepSHA256 填充

Posted

技术标签:

【中文标题】覆盖 RSA 对象中的默认算法以支持 OaepSHA256 填充【英文标题】:Override default algorithm in RSA object to support OaepSHA256 padding 【发布时间】:2019-09-06 04:56:34 【问题描述】:

在 .Net 4.6 中创建 RSARSACryptoServiceProvider 对象默认为 KeyExchangeAlgorithm RSA-PKCS1-KeyEx,它仅支持 OaepSHA1 填充。

在尝试使用“OaepSHA256”等其他填充时,获取“指定的填充模式对此算法无效”。

有没有办法将 RSA 对象中的算法覆盖为支持此填充以使其支持所有填充的算法。

更新 RSACng 有效。在我的场景中,我使用容器密钥将私钥存储在机器中,使用 RSACryptoServiceProvider 在需要时使用容器密钥名称检索私钥。作为使用 RSACng 的一种解决方法,我正在导入从 RSACryptoServiceProvider 对象导出的属性,如下所示。有一个更好的方法吗?

using (var rsa = new RSACryptoServiceProvider(cspParams))
            
                using(var rsaCng = new RSACng())
                
                    rsaCng.ImportParameters(rsa.ExportParameters(true));

                    decryptedResult = rsaCng.Decrypt(encryotedText, RSAEncryptionPadding.OaepSHA256)
                
            

【问题讨论】:

“在 .Net 6.0 中”- 没有 .NET 6.0。请说明您的目标平台。 KeyExchangeAlgorithm 属性没有实际意义,您应该忽略它。但是你需要使用 RSACng,而不是 RSACryptoServiceProvider。 抱歉.NET 4.6的错字 感谢 RSACng 的作品。在我的场景中,我使用容器密钥将私钥存储在机器中,使用 RSACryptoServiceProvider 在需要时使用容器密钥名称检索私钥。作为使用 RSACng 的一种解决方法,我正在导入从 RSACryptoServiceProvider 对象导出的属性,这听起来不错。有没有更好的办法? 感谢@Dai RSACng 工作。更新中提供的解决方法中的任何 cmets 【参考方案1】:

RSA 自 .NET Framework 4.6 起在 .NET Framework 中支持 OaepSHA256,自 1.0 起在 .NET Core 中支持(以及 OaepSHA1OaepSHA256OaepSHA384OaepSHA512 和 PKCS 标准#1,see the documentation here)。

至于对旧版本 .NET Framework 的支持 - 我不认为这是可能的,因为 Cryptography API 将加密算法实现视为不透明的黑盒,没有太多可扩展空间(即,您不能真正将现有实现子类化,但你可以很容易地重新实现你自己的)。我注意到这部分是因为 API 只是包装了 Windows 的内置加密功能,无论如何都是不透明的(就像 System.Drawing 包装 GDI 时也没有太多扩展空间)。

至于“指定的填充模式对此算法无效”错误 - 问题是您使用的是 RSACryptoServiceProvider 而不是 RSACng。您应该更喜欢 Cryptographic-Next-Generation (Cng) 实现而不是 CryptoServiceProvider 实现 see this article for more details。

如果您的目标是 .NET Framework 4.6 或更高版本,或者 .NET Core 1.0 或更高版本,您可以像这样使用它:

using Sytem.Security.Cryptography;

Byte[] inputPlaintext = ...
RSAEncryptionPadding oaepsha256 = RSAEncryptionPadding.OaepSHA256;
using( RSA rsaImpl = new RSACng() )

    Byte[] ciphertext = rsaImpl.Encrypt( inputPlaintext, oaepsha256 );

【讨论】:

以上是关于覆盖 RSA 对象中的默认算法以支持 OaepSHA256 填充的主要内容,如果未能解决你的问题,请参考以下文章

JAVA RSA非对称加密详解

RSA/SHA1加密和数字签名算法在开放平台中的应用

Android中自带的RSA加密算法和JAVA中的不是一个标准的吗?

密码学之公钥密码体系:RSA算法

SSL/TLS深度解析--OpenSSL 生成自签证书

密码学——公钥密码体系之RSA算法2