Cryptographic Right Answers
daemonology.net
daemonology.net
For instance, CTR+HMAC is a weird recommendation. Not because of speed (though HMAC does pessimize speed) and not because of cryptographic strength, but because it introduces another moving part in your design. Colin can deal with the junction between plaintext, ciphertext, and HMAC, because this is mostly all he thinks about. You can't.
A simpler recommendation would have been to use CCM or EAX mode. These have the advantages of being NIST standards-tracked and heavily vetted, and of providing both authentication and encryption in the same construction. If your libraries are good, you get both these features just by switching the name of your block mode.
Second, I'll quibble with the content of the post: these recommendations are exactly what Nate was talking about in his Yahoo talk about how bad cryptographic guidance has gotten. Key size and hash function selection (as long as you're not using MD5) are the least important design considerations you have.
Here's a design consideration this post doesn't even touch on: renewability. How do you safely design a system so that your selection of algorithms, modes, and key sizes isn't set in stone? Because if you don't get that right today, what you inevitably do to handle it 2 years from now is going to be a vulnerability.
Finally, a real concern about the structure of these recommendations: telling people to keep group negotiation out of Diffie-Hellman protocols is fine --- a good recommendation, since there's a really scary sounding, really easily-exploitable vulnerability that eliminates. But that's --- I think --- the only place in this post where Colin actually addresses something that actually does go wrong in crypto protocols.
If you follow all of Colin's recommendations here from scratch in a reasonably complicated, and you have never found a crypto vulnerability or fixed two reported crypto vulnerabilities, I will bet $500 that you end up with a broken system. Colin won't. But you will.
All of your recommendations die in embedded applications, where nobody will use HMAC-SHA256 (or SHA256 at all) or RSA.
;)
There are certainly applications where I would revise my recommendations, but embedded isn't particularly one of them.
Encrypt-then-HMAC has been a widely used standard for the past decade, and has been extensively studied.
A simpler recommendation would have been to use CCM or EAX mode.
AES-CTR and HMAC-SHA256 are far more simple than AES-CCM or AES-EAX. AES-CTR plus HMAC-SHA256 is also far more secure against side channel attacks, and has the advantage of allowing you to separate authentication from encryption -- useful if, say, you want to include some unencrypted data in an authenticated packet as well.
Key size and hash function selection (as long as you're not using MD5) are the least important design considerations you have.
I didn't mean to imply that all of the issues I mentioned were very important. My selection was more or less done on the basis of "what questions have people asked me recently?"
If you follow all of Colin's recommendations here from scratch in a reasonably complicated, and you have never found a crypto vulnerability or fixed two reported crypto vulnerabilities, I will bet $500 that you end up with a broken system.
That's probably a safe bet. I think it would be an even safer bet if you made it with someone who didn't follow my recommendations.
The same goes double for your second point. Yes, if you have to implement the MAC yourself, you clearly want to use HMAC rather than trying to get CBC-MAC right. But if you're in a place where you have to implement your own MAC, you are doomed for a bunch of other reasons. CCM is preferable to HMAC because it's likely you're going to simply be able to change CTR to CCM and have it.
I didn't say anything about implementing the MAC yourself. Someone has to implement it, though -- and no matter who writes the code, HMAC-SHA256 is far more likely to be right and not leaking data via side channels than CBC-MAC is.
The point is that there are already shrink-wrapped AE constructions (like CCM or EAX) that you can pick up off the shelf and use; HMAC designs are more likely to be bespoke.
If you trust the library, sure. But I've found that the same rules apply to crypto libraries as to everything else: Obscure and complicated features are far more likely to be buggy.
No crypto library is ever going to ship with a broken HMAC-SHA256 -- but I can't say the same thing about AES-CCM.
CCM and EAX aren't obscure. AE crypto has been in 3 of the last 4 designs I've had to review. The fourth prompted a recent blog post of mine.
You're right that stream ciphers blow up more spectacularly than block encryption does. You have to be sure not to re-use anything (counters, nonces, keys, etc). If "don't overfill a buffer" is an easy prescription that cost industry $4+bn USD, it's hard to imagine how unlikely it is people can avoid screwing up "don't reuse anything".
On the other hand, differentiatable errors cause spectacular problems with block encryption. See: the "bad padding" error message that decrypts entire AES blocks a byte at a time.
I don't understand the collision problem very well either. I know it's been used to crack a certificate here or there, but it seems like it took a lot of resources to crack one password.
http://www.mscs.dal.ca/~selinger/md5collision/ has some great, and very scary examples.
"Client-server application security: Distribute the server's public RSA key with the client code, and do not use SSL."
It seems like the point of this is to make sure that when communication moves from the client, only the server with the proper private key can decrypt it - BUT, aren't you just going to use OpenSSL to implement this (via TLS)? Is there some other way to accomplish this I'm not aware of? What's he specifically warning us against?
In fact, never implement your own cryptographic protocol unless you _really_ have to. And even then, think twice.
For example, as of Rails 2.3, ActiveResource (the default RESTful web service API client used in many Rails applications) disables all SSL verification whenever SSL is used, without so much as a configuration flag to enable it again.
If you can establish relationships between members of your protocol, you can rely on continuity for security. Continuity is what SSH uses. It's easier than authority, and it's sane to recommend that people take advantage of it when possible.
But when your users will constantly be enrolling new participants into your system, continuity becomes a huge design risk, just like how everyone used to lose their SSH keys to sniffers at Usenix Security.
You should be clearer with your recommendation. If you can relax the constraint that the protocol has to work between strangers, then SSL offers functionality you don't need, and the actual interface to SSL has moving parts that might hurt you.
Most people who build crypto can't relax that constraint, even if they think they can. We've beat several schemes that relied on pre-distributed public keys because of the out-of-band channels that wound up getting grafted on to bring new members into the group.
Finally, verifying a certificate chain isn't hard. It's constructing a verifiable certificate chain in the first place that has proven difficult. If IE7 didn't offer the "bad certificate" click-through warning, and simply failed the request, we'd be discussing the right problem instead of the red herring.
I specifically mentioned client-server applications, didn't I? If you are handing out client code which talks to a server you run, you don't need the protocol to work between strangers.
If an attacker can mangle the server public key which you're distributing with the client code, they can mangle the client code, at which point you've already lost.
Just so we're clear.
"Don't use a signed server certificates, etc... when you don't have to, instead use a RSA public key."
It was the OpenSSL thing that confused me. I forget that TLS is way more than RSA over TCP sometimes. Thanks for the clarification.
One thing people reading it may not realize is the importance of picking good IVs and the necessity of including them in the MAC.
Someone might just authenticate the ciphertext and neglect to include the IV, leaving themselves open to a few attacks.
In contrast, most crypto rants fall into the "laugh at them, as they're all equally stupid" trap, which is not going to change humans into better...
"Do NOT store users' passwords. Do NOT hash them with MD5. Use a real key derivation algorithm. PBKDF2 is the most official standard; but scrypt is stronger. Please keep in mind that even if YOUR application isn't particularly sensitive, your users are probably re-using passwords which they have used on other, more sensitive, websites -- so if you screw up how you store your users' passwords, you might end up doing them a lot of harm."