Why Can't I Change the KeySize of Asymmetric Algoritms or: The Joys of Backwards Compatibility

Here's a little quirk that can definitely cause a lot of confusion.  When I run the following code snippet, what do you suppose the output will be:

RSA rsa = new RSACryptoServiceProvider();
Console.WriteLine(rsa.KeySize);
rsa.KeySize = 4096;
Console.WriteLine(rsa.KeySize);

If you guessed 1024 and 4096, you're in for a surprise when you try running the code.  Instead the result is actually 1024 and, well, 1024.

Modifying the KeySize property of RSACryptoServiceProvider or DSACryptoServiceProvider won't actually change the key size.  However, it won't throw an error either.  Instead, it will just silently accept the new key size and do nothing about it.  In fact, it won’t even update the value you get out of the KeySize property.

This seems like a simple thing to fix for Whidbey, right?  Well, here's where the joys of maintaining backwards compatibility come into play.  There are two options for a fix:

  1. Provide a KeySize setter that throws an exception
  2. Generate a new key of the specified size whenever KeySize is set

Option one will clearly break any application that attempts to set KeySize on one of the asymmetric implementations, since we will now throw an exception where we didn't before.

Option two is also a break, since any application that uses this property will now be using keys of a different size.  The case is easily made that this is a bug in these applications, however, that doesn’t make the change on our end any less breaking for them.

Since the bar for allowing a breaking change into the platform is very high, neither of these are acceptable.  Instead, if you'd like to create a key with a different key size than the default, you should use the constructor overload that takes a key size parameter.  This method has always worked, and will continue to work in Whidbey.  And if you'd like a bin to throw your garbage bits into, you can continue to use RSACrytpoServiceProvider.KeySize :-)