Search code examples
c#encryptioncryptographypaddingrsacryptoserviceprovider

RSACryptoServiceProvider doesn't produce consistent output


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.


Solution

  • 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.