3

I need to encrypt some text with RSA, and then recover it later using the private key. My problem is that RSACryptoServiceProvider.Encrypt() outputs a different value every time, even when using the same key. Here is my code which I put into LINQpad to test:

CspParameters cp = new CspParameters();
cp.KeyContainerName = "MyKey";
cp.Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey;

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

// using LINQpad to verify the key is loaded properly -- same every time
rsa.ToXmlString(true).Dump();

byte[] rgb = new ASCIIEncoding().GetBytes("Hello world");
byte[] xx = rsa.Encrypt(rgb, false);
string b64 = Convert.ToBase64String(xx);

// this changes every time:
b64.Dump();

I'm guessing that the class must be using something else as well as the key to affect the output, but I'm struggling to find out what.

poupou
  • 43,413
  • 6
  • 77
  • 174
Gordon Leigh
  • 1,263
  • 2
  • 11
  • 23
  • When you decrypt the data, do you get the same result every time? – robert Oct 28 '11 at 11:59
  • Well I thought I didn't. Which is why I took it all back to looking at the encrypted text to see that it was the same. But I couldn't repro the problem before I went to update my answer -- I think I mixed up the padding types in the second param of Encrypt(). – Gordon Leigh Oct 28 '11 at 12:37

2 Answers2

1

The fact that the cipher text is different each time the same cleartext is encrypted doesn't mean that it cannot be decrypted consistently.
This is indeed the sign of a good cryptographic algorithm to have be able to have this behavior, making it more resilient to various attacks.

This is because the the encryption logic introduces randomness in the process, for example by systematically adding some random bytes before the cleartext itself. So long as the decryption logic knows to ignore these bytes after the whole ciphertext is decrypted then it can reproduce the original cleartext.

I suggest you take any instance of this b64 text, submit it to the reverse process and see that the "rgb" produced is "Hello world" in all cases.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
mjv
  • 73,152
  • 14
  • 113
  • 156
1

The different output is perfectly normal. This is due to the fact that your data is being padded by PKCS#1 or OAEP - and both are using/adding some random data.

Now this is not how you should be using RSA. Many reasons but the most direct, for you, is because the padding / block size is limiting the number of bytes you can encrypt (and RSA is too slow to consider looping encrypting blocks).

I wrote a blog entry on the subject that describe how you can mix symmetric (better speed, no size limit) with asymmetric encryption - getting the best of both worlds :-)

poupou
  • 43,413
  • 6
  • 77
  • 174