Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can RSACryptoServiceProvider (.NET's RSA) use SHA256 for encryption (not signing) instead of SHA1?

When encrypting, can RSACryptoServiceProvider (or any other RSA encryptor available from .NET) use SHA256 instead of 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".

If there is no way to make RSACryptoServiceProvider use SHA256, what are the alternatives?


Update

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?

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);

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);
like image 830
Jonathan Wright Avatar asked Feb 25 '11 04:02

Jonathan Wright


People also ask

Does RSA use SHA256?

SHA256 with RSA signature is an efficient asymmetric encryption method used in many secure APIs. This algorithm first calculates a unique hash of the input data using SHA256 algorithm. The hash is then encrypted with a private key using the RSA algorithm.

Why it is not recommended to use RSA for encryption?

RSA is an intrinsically fragile cryptosystem containing countless foot-guns which the average software engineer cannot be expected to avoid. Weak parameters can be difficult, if not impossible, to check, and its poor performance compels developers to take risky shortcuts.

What is the difference between SHA and RSA?

SHA is a 'one-way' encryption algorithm.It means you can't reach the input text by having output(result of algorithm). RSA is a 'two-way' encryption decryption algorithm. It means you can reach input data(raw text) by having output (ciphered or encoded text).


1 Answers

RSACryptoServiceProvider does work with SHA2-based signatures, but you have to invest some effort into it.

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.

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"));

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"));
like image 70
Vladik Branevich Avatar answered Oct 24 '22 09:10

Vladik Branevich