Update 11/24/11: Bram has responded my criticisms in this post. See the comments section below for his thoughts and my response. Also, see this new post for my more detailed response.
I was innocently Googling the title of my blog (yes, I do this, it’s sad) when I came across this May 2011 post by Bram Cohen entitled “Practical Cryptography Corrected“.
Ostensibly the post is a criticism of Bruce Schneier’s book Practical Cryptography. Instead, it’s proof that inventing the world’s most useful peer-to-peer protocol does not make you a cryptographer. More worrisome than that, it’s an example of someone with a big megaphone using it to give really bad advice.
Bram’s post has ten points, of which four are (somewhat) problematic. Let’s take them one at a time.
Bram’s Practical Advice #1: For an RSA exponent, you should always use 2. Technically that’s Rabin-Williams, and requires slightly different implementation, but that actually works in its favor. Rabin-Williams has a reduction to factoring, RSA does not.
No, no, no. A thousand times no.
If you’re going to encrypt with RSA, you should encrypt with RSA. That means using a standard, well-tested RSA implementation with the traditional RSA public exponent (e = 0x10001).*
Unless you’re an expert, do not go switching your exponents around. Rabin-Williams (public exponent 2) looks like RSA, but it’s a very different cryptosystem — both in how decryption works and in what goes wrong if you screw up your implementation.
For one thing, when you implement Rabin-Williams incorrectly, it becomes vulnerable to a chosen ciphertext attack that completely recovers the scheme’s secret key. RSA does not have this problem. This issue can be managed through skillful use of padding**, but your typical from-scratch implementer is not skillful. Even bad implementations of good padding can lead to problems. Why chance it?
Which brings me to my first law: The probability that your RSA ciphertext will be broken via some number-theoretical attack is vanishingly small. The probability that it will be broken because you screwed up your implementation, on the other hand, is high. All current approaches to solving the RSA problem work by attacking the factoring problem anyway, so it’s unclear what advantage we’re buying ourselves here.
Bram’s Practical Advice #2: You should always do encryption as a layer outside of authentication.
Cryptographers have been arguing the order of encryption and authentication for nearly thirty years. Should you encrypt first, then apply authentication (a MAC)? Or should you authenticate first, then encrypt?
By 2000 we had basically put this question to bed. The recommended best practice? Always encrypt first (with a strong cipher and mode of operation), then apply a MAC to the resulting ciphertext. This isn’t just easy to remember, it’s provably secure against adaptive chosen ciphertext attacks. That means you’re protected against very real issues like padding oracle attacks. Bram’s technique doesn’t give you this, and that can spell disaster.
Bram’s Practical Advice #3: For an encryption mode, you should always use CTR, and always use a nonce of zero, and never reuse keys.
Bram’s Practical Advice #4: You should never use the same key for both encryption and authentication. If you need both encryption and authentication, you should use two keys. One for encryption, and one for authentication.
I have only two points to make: first, why not use a random IV? What’s going to happen to you if you hard-code a zero IV, and then the next (idiot) developer switches your mode of operation to CBC? This shouldn’t happen, but it might.
But more generally, my advice is not to use CTR at all. Use a provably-secure authenticated mode of operation like CCM, OCB or (best) GCM, in the way recommended by standards. These modes handle both encryption and authentication for you, and better yet — they all use a single key (by design). You’re much better off using these standards than hand-rolling your own encrypt/MAC approach (especially if — per Bram’s Advice #2) you plan on doing it wrong.
I have a lot of respect for Bram, and if I come off a bit critical in the post above, it’s isn’t because I dislike the guy. In fact, many of his remaining points are good.
But the only thing worse than bad advice is bad advice from a voice of authority. And Bram has a lot of authority, which could lead people to trust him over some goofy, non-famous cryptographer (or even Bruce Schneier, for some crazy reason).
Fixing people’s cryptographic mistakes has given me a good living so far, but that doesn’t mean I like it. So please, please don’t listen to Bram. Do things right, follow standards, and most importantly: if you don’t know exactly what you’re doing, don’t do it at all.
* I initially wrote “e = 100001” which is totally bogus. Goes to show you shouldn’t trust a blog post. Thanks to GSBabil.
** Use of padding, incidentally, completely breaks the reduction to factoring unless you conduct the proof in the Random Oracle Model. And as I discuss here, there are some serious problems with that.