问题描述
加密时,RSACryptoServiceProvider(或 .NET 提供的任何其他 RSA 加密器)是否可以使用 SHA256 而不是 SHA1?
When encrypting, can RSACryptoServiceProvider (or any other RSA encryptor available from .NET) use SHA256 instead of SHA1?
SHA1 似乎是硬编码的,无法更改.例如,RSACryptoServiceProvider.SignatureAlgorithm 被硬编码为返回http://www.w3.org/2000/09/xmldsig#rsa-sha1".
SHA1 appears to be hard coded with no way to change it. For example, RSACryptoServiceProvider.SignatureAlgorithm is hard coded to return "http://www.w3.org/2000/09/xmldsig#rsa-sha1".
如果没有办法让 RSACryptoServiceProvider 使用 SHA256,有哪些替代方案?
If there is no way to make RSACryptoServiceProvider use SHA256, what are the alternatives?
更新
以下代码完美运行,但我想将 OAEPWithSHA1AndMGF1Padding 更改为 OAEPWithSHA256AndMGF1Padding.C# 端需要什么才能使用 SHA256 而不是 SHA1 进行加密?
The following code works perfectly, but I'd like to change the OAEPWithSHA1AndMGF1Padding to OAEPWithSHA256AndMGF1Padding. What is required on the C# side to be able to encrypt using SHA256 rather than SHA1?
加密在 C# 中使用:
The encryption is done in C# using:
var parameters = new RSAParameters();
parameters.Exponent = new byte[] {0x01, 0x00, 0x01};
parameters.Modulus = new byte[] {0x9d, 0xc1, 0xcc, ...};
rsa.ImportParameters(parameters);
var cipherText = rsa.Encrypt(new byte[] { 0, 1, 2, 3 }, true);
解密是在 Java 中使用:
The decryption is done in Java using:
Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
byte[] cipherText = ...;
byte[] plainText = cipher.doFinal(cipherText);
推荐答案
RSACryptoServiceProvider 确实可以使用基于 SHA2 的签名,但您必须投入一些精力.
RSACryptoServiceProvider does work with SHA2-based signatures, but you have to invest some effort into it.
当您使用证书获取 RSACryptoServiceProvider 时,底层 CryptoAPI 提供程序是什么真的很重要.默认情况下,当您使用makecert"创建证书时,它是RSA-FULL",它仅支持 SHA1 哈希进行签名.您需要支持 SHA2 的新RSA-AES".
When you use a certificate to get your RSACryptoServiceProvider it really matters what's the underlying CryptoAPI provider. By default, when you create a certificate with 'makecert', it's "RSA-FULL" which only supports SHA1 hashes for signature. You need the new "RSA-AES" one that supports SHA2.
因此,您可以使用附加选项创建证书:-sp "Microsoft Enhanced RSA and AES Cryptographic Provider"(或等效的 -sy 24),然后您的代码将如下所示(在 .NET 4.0 中):
So, you can create your certificate with an additional option: -sp "Microsoft Enhanced RSA and AES Cryptographic Provider" (or an equivalent -sy 24) and then your code would look like (in .NET 4.0):
var rsa = signerCertificate.PrivateKey as RSACryptoServiceProvider;
//
byte[] signature = rsa.SignData(data, CryptoConfig.CreateFromName("SHA256"));
如果您无法更改颁发证书的方式,则有一个半合法的解决方法,该解决方法基于默认情况下创建 RSACryptoServiceProvider 并支持 SHA2.因此,下面的代码也可以工作,但它有点丑:(这段代码的作用是创建一个新的 RSACryptoServiceProvider 并从我们从证书中获得的密钥中导入密钥)
If you are unable to change the way your certificate is issued, there is a semi-ligitimate workaround that is based on the fact that by default RSACryptoServiceProvider is created with support for SHA2. So, the following code would also work, but it is a bit uglier: (what this code does is it creates a new RSACryptoServiceProvider and imports the keys from the one we got from the certificate)
var rsa = signerCertificate.PrivateKey as RSACryptoServiceProvider;
// Create a new RSACryptoServiceProvider
RSACryptoServiceProvider rsaClear = new RSACryptoServiceProvider();
// Export RSA parameters from 'rsa' and import them into 'rsaClear'
rsaClear.ImportParameters(rsa.ExportParameters(true));
byte[] signature = rsaClear.SignData(data, CryptoConfig.CreateFromName("SHA256"));
这篇关于RSACryptoServiceProvider(.NET 的 RSA)可以使用 SHA256 进行加密(不是签名)而不是 SHA1 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!