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:
- Provide a KeySize setter that throws an exception
- 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 :-)
Comments
- Anonymous
September 28, 2004
Can the setter at least be obsoleted in this release so that it's eligible for removal in the future? It seems unlikely that this will ever get fixed.
Although really this seems like a security exploit waiting to happen. You're fooling users of this API into thinking they have strong protection when in fact they may be vulnerable due to a low strength method. - Anonymous
September 28, 2004
we [the developers consuming your products] cannot continue to expect backward compatibility with newer versions of the framework... this is the whole point of SxS installations!
we [the developers] should always RETEST our products when WE decide to use newer framework versions...
come on guys... ! I think you've got the mentality that we're stupid or something... fix the problems and DO IT RiGHT. Mistakes happen... DONT PERPETUATE them. - Anonymous
September 28, 2004
I've heard that Microsoft developers have regular "security drives". Does this top ever come up at one of these meetings? From your tone, I don't get the impression that you've taken a very hard look at the security aspect of the problem. Rather it appears that you are seeing this merely as a matter of elegance.
This kind of mentality obviously isn't helping Microsoft's security initiative. - Anonymous
September 28, 2004
The comment has been removed - Anonymous
September 28, 2004
The comment has been removed - Anonymous
September 28, 2004
The only correct proposal: Create a FxCop rule for this !! - Anonymous
September 28, 2004
This whole issue is interesting. I don't want to sound challenging, but it could be phrased as 'microsoft treats backward compatibility as more important than security', which is probably not the best message you can send out to the world.
I think that at least some mechanism should be added that will cause alarm bells to go off, preferably at compile time, when this setter is called. Or, alternatively, add some mechanism that will cause the setter to throw an exception (NotSupportedException, for instance) if a certain administrative action has taken place (for instance by setting a flag in the application configuration file, or event the system configuration files). This will give people the warm feeling that, in the case some software triggers this feature they will get informed about it, instead of not being made aware that the wrong key size is being used.
Frankly, I think this is a case where MS has to swallow the bitter pill, and security has to be prioritized over backward compatibility. Add those exceptions, or remove the setter, even if it will break existing software.
Btw, I disagree with AT. Yes, adding an FxCop rule is a good idea, but not everyone will run FxCop, and this is something that everyone needs to be aware of, so it cannot be the only solution. - Anonymous
September 29, 2004
I completely agree with Luc Cluitmans.
When you say lotus 1-2-3 is still running on... Yes. But this is different. There is no security issue to make lotus running.
If not so, why fixing any bug? Some older applications may use this bug as a fact and beeing manufactored to take it into account.
This is a normal process to correct an application even if I understand that a framework is a special kind of application. - Anonymous
September 30, 2004
So we've taken everything into consideration. The LegalKeySize idea that Nicholas presented is a good and very creative one, however in many ways that would be more breaking than fixing the original bug. (Think of someone who news up a RSACryptoServiceProvider, then uses LegalKeySizes to see what size keys are available on that machine).
The FxCop rule is a very good idea, and most likely the route that we'll end up taking on this. Great suggestion AT.
-Shawn - Anonymous
October 09, 2004
The comment has been removed