RSACryptoServiceProvider(.NET 的 RSA)可以使用 SHA256 进行加密(不是签名)而不是 SHA1 吗? [英] Can RSACryptoServiceProvider (.NET's RSA) use SHA256 for encryption (not signing) instead of SHA1?

查看:28
本文介绍了RSACryptoServiceProvider(.NET 的 RSA)可以使用 SHA256 进行加密(不是签名)而不是 SHA1 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

加密时,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 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆