Hacker News new | ask | show | jobs
by schabernakk 4765 days ago
When he is saying

>Save yourself the trouble. Don't use cryptography. It is plutonium. There are millions of ways to mess it up and precious few ways of getting it right.

I am sure he means don't use your own homegrown cryptography solution. Use something established and well tested. Good advice, probably can't be repeated enough. I liked the exampled he gives, I didnt know for example that you can basically extend an MD5ed string and keep the original MD5 value. Then again, I know that MD5 isn't a secure cryptographic hash function so I wouldn't have used it from the start. Nice to know why thats the case.

3 comments

Hi, author here, I'm glad you found it useful!

> I didnt know for example that you can basically extend an MD5ed string and keep the original MD5 value

Thank tptacek for that knowledge, I think I picked it that up in a talk he did that's somewhere on Vimeo (will link to it).

> Then again, I know that MD5 isn't a secure cryptographic hash function so I wouldn't have used it from the start. Nice to know why thats the case.

Nope! I was going to mention in this in the post but removed it to keep things simple: This particular vulnerability is not due to MD5 collisions or MD5 being cryptographically insecure. It's because of the internal mechanism (a "Merkel Damgard Construction") intrinsic to hash functions like MD5, SHA1, SHA256 and friends. Even if MD5 were cryptographically secure, this vulnerability would still present itself if used in the way I described.

Don't mean to nitpick, but with crypto small misunderstandings lead to big vulnerabilities. Hope that makes sense :)

> It's because of the internal mechanism (a "Merkel Damgard Construction") intrinsic to hash functions like MD5, SHA1, SHA256 and friends. Even if MD5 were cryptographically secure, this vulnerability would still present itself if used in the way I described.

Thanks for pointing that out, didn't know that.

Just for fun, if they had written message+secret instead of secret+message it would have been ok (although bad practice)?

calculated_mac = OpenSSL::Digest::MD5.hexdigest(message+secret)

Secret suffix MACs are insecure if your hash function isn't collision-resistent. To illustrate: MD5 isn't collision-resistent, but HMAC-MD5 has no currently known viable attacks, because it isn't simple a secret-suffix MAC.

So it's true that using a secret-suffix MAC is safer than using a secret-prefix MAC, but if you know enough to make that choice, you know enough to use HMAC.

The answer is no, but I forget the exact reason why. Will do a little more research and report back.
>This particular vulnerability is not due to MD5 collisions or MD5 being cryptographically insecure. It's because of the internal mechanism (a "Merkel Damgard Construction") intrinsic to hash functions like MD5, SHA1, SHA256 and friends.

That's what I like about SHA3. It only dumps part of its internal state so there is no possible way to resume from a hash. This also makes it viable as a PRNG or cipher stream.

Is there a repository or central location of the established and well tested solutions for developers to use? Where does one start?
Some ideas, depending on what you need (I can't say how good these are):

http://www.keyczar.org

http://nacl.cr.yp.to

https://github.com/jedisct1/libsodium

http://www.gnupg.org

Thanks. These are straight crypto frameworks which are a good start.
One of the problems with cryptography is that "solutions" are not as generally applicable as one might want. There are a lot of assumptions that are made, and violating those assumptions is usually a disaster.

For example, when it comes to encryption, it is typically assumed that all messages are the same length. If your application does not make this guarantee, encryption may not provide you with any security. You could wind up in this situation:

https://news.ycombinator.com/item?id=2661890

Think of it this way: asking for a list of tried-and-true crypto solutions is like asking for a list of tried-and-true database schemas. There might be cases where it will work, but for the most part you need to put some thought into what you are doing.

That makes sense in terms of no standard libraries. But how about design patterns for common scenarios, eg. securing REST apis, User authentication/Login/Signup, Payment information handling etc, all in one place.

Does it become less secure if everyone follows standard design patterns?

No, of course it does not become less secure. In the worst case, slapping some crypto onto a system would have no effect at all; it is hard to see how it could make things worse, other than to give people a false sense of security.

An example is Hushmail. Your mail is signed, it is encrypted, you're using the tried-and-true PGP...and the DEA can walk into court with a pile of DVDs full of the plaintext of some defendant's email. Hushmail is, at best, only marginally more secure than GMail.

So while we might come up with good practices for using cryptography, it is inevitable that organizational practices will render the cryptography pointless. Solutions need to be tailored to the specific needs of an organization or a system. That is where the real problem lies: we do not have something like SQL for cryptography. We do not have a good way to specify organization needs and design (or even verify the security of) a cryptosystem that meets those needs.

Wikipedia perhaps?
Doesn't matter if it's MD5 or SHA512. You can extend either hash function in the exact same way (http://en.wikipedia.org/wiki/Length_extension_attack)
It does matter what hash function you use, though. MD5 and SHA-512 are both vulnerable to length extension, but there are other hash functions that are not, like SHA-512/256, SHA-3 or BLAKE.

The documentation for both Keccak and BLAKE2 recommend prefixing a fixed-length key to the message to do MAC, pretty much like in the vulnerable example, but with a better hash function.

> other hash functions that are not, like SHA-512/256

I think you meant SHA-224/384. Both SHA-512 and -256 are vulnerable to length extension because their internal state is dumped and resumable. With SHA-224/384, you only get a truncated state (from 256- and 512-bits respectively), which you can't pick up and resume.

I do mean the hash function "SHA-512/256", as defined in FIPS 180-4 [1]. It is basically a version of SHA-512 that truncates the final result to 256 bits (Like SHA-384). It is not vulnerable to length extension, because unlike SHA-256, the final hash does not contain enough state to continue hashing.

I wouldn't consider SHA-224 immune to length extension since it only truncates 32 bits, which is low enough to brute force.

[1] http://csrc.nist.gov/publications/drafts/fips180-4/Draft-FIP...

Ahh, quite right. Sorry about that. And yeah, I agree on SHA-224; it's okay in certain circumstances (you're rarely going to be able to pull off 2^31 (average) requests), but it's almost definitely not the right choice.