This quote, attributed to Whitfield Diffie, pretty much sums up this post: “A secret that is hard to change is a vulnerability.“
I've been thinking about this a lot lately as I see more and more systems that violate this rule. Take strong names as an example. When strong names were first introduced in verison 1 of the .NET Framework, I thought, “what a cool idea: instead of using GUIDs to identify pieces of code, use a public key, because it can double as a way to add tamper detection, author identity, etc.“ But the more I worked with the .NET Framework, the more I realized that using an RSA key as an identifier is actually a liability, not an asset. It's just adding another secret to your life that you wouldn't have had before. How many of you even bother to protect the private key for your strong names? I've seen more than one case where people shipped the key pair in a file along with their binaries.
Here's the question you should ask yourself whenever you see a secret in a system: “How painful would it be to change that secret?“ How painful would it be for you to change the RSA key pair that you use to sign your assemblies? If you're using GAC versioning, you probably know that as soon as you change the public key (which changes the public key token) you've got an entirely new assembly as far as .NET is concerned - you've broken the versioning chain. Ouch. Oh, and did you realize that it's really easy for sysadmins to hang code access security policy off of a strong name? That policy is only as strong as the private key is secure! How do you revoke such a key if it's compromised? Once you start thinking about these issues, you may come to the same conclusion I did: “Why the hell do we have secrets as part of the assembly naming story at all?“ Hindsight is 20/20 - it sure did seem like a cool idea at first.
That's why we need to think about this earlier rather than later. As soon as you find yourself tempted to design a secret into a system, you'd should make sure your design makes that secret easy to change, otherwise it's likely to cause more harm than good. Cryptography is a dangerous panacea, “Social security numbers? No sweat, we've got 256-bit encryption!“ nevermind the fact that the private key ultimately protecting everything hasn't been changed since the system was deployed.
What do cryptographers call keys that are hard to change? I've been searching the net to find if there's a term for this, because I think it would be a useful addition to the lexicon. I've not yet found anything, so I'm tempted to suggest the term, “Heavy keys“. Lightweight keys are easy to change - many of them you don't even need to think about (consider a machine's password in a domain - it's automatically changed every 7 days, and many sysadmins don't even realize it exists). Heavy keys are so painful to change that in practice they never do.
Here's a bit of a different example: ASP.NET's machineKey. There's no versioning story behind that key; if you change it, anybody who has outstanding forms login cookies or viewstate will have trouble the next time they connect to the server. The login cookie is the least problematic - the user will simply be prompted to log in again (not that I've tested this, but it's the best possible outcome). With viewstate, an exception will be thrown as the state won't validate and the server will think it's been tampered with. These things may not be huge issues in the big scheme of things, but consider what happened in version 2.0 when the SqlMembershipProvider was added. Now you've got a provider that will happily encrypt user passwords for you using a non-versioned key. Now what happens when you change out that machineKey? Suddenly when your existing users attempt to log in, they are denied access because you can no longer validate their passwords. And if you didn't back up the old key, you'd better start shining up your resume. If you plan ahead, you can work around this, but you'll need to write the code yourself to rekey the user database.
What's interesting about the machineKey example is this: here we have a key that already was a bit heavy (no support for versioning), but it suddenly got much heavier because of one feature (encrypted passwords). At that point, completely unrelated features (viewstate protection, forms login cookies, etc.) began to suffer because the one key protecting all of them suddenly became difficult to change.
There are probably a lot of people who don't realize how important it is to change out keys regularly. Consider the uncomfortable position you may be in when your sysadmin quits and goes to work for your competition, taking your machineKey with him. Keep in mind that the longer a cryptographic key is used, the weaker and more valuable the key becomes, especially when persistent data is protected (directly or indirectly) with that key. Heavy keys as a category on Ebay - wouldn't that be a kick?
Now we have InfoCard (well, CardSpace), which is really what got me thinking about this. But I think this post is probably useful on its own, so I'll talk about CardSpace keys in another post. But for now, I'm curious - where have you guys seen heavy keys? Leave a comment if you know of such a system. Extra points if it's a system we all use regularly!
Posted
Jun 16 2006, 01:56 PM
by
keith-brown