I don’t necessarily agree with what’s here, but it seemed worthy of consideration or discussion.
Every framework I know has had at least one spectacular HMAC failure. It’s far from foolproof, and as soon as you go off the beaten path and using it for something that your (hopefully) audited framework, there’s a chance you’ll plow straight into the same mistakes.
Some mistakes are trivial to avoid (use real HMAC, not a simple hash(secret + msg)), but they’re also among the most common in the wild.
I don’t think I can agree with the implicit conclusion that you’re more likely to screw up “delete old tokens from database” than “securely cryptomogrify magic tokens”.
I Googled cryptomogrify out of curiosity. Congratulations, according to Google you are the only person on the internet to use this word.
[Comment removed by author]
Haha, it always is!By the way, Racket just HMAC-signs the continuation as a whole. I am not even sure if it adds an expiration and I am not aware of any salting, but the algorithm is pluggable.
If I have the choice between using a battleproof database and deploying my own crypto system in the wild, I’ll go with a db every single day. You will get the crypto wrong. It might seem exciting and cool, but the odds are clearly against you - and your users.
Not necessarily true. If you are familiar with crypto primitives you can make well designed schemes to achieve what this article describes. I would prefer that the tone was “learn about crypto because it has real world use” rather than “look this stuff is easy,” because it’s not easy.
The author uses simple examples, a fixed number of required fields. If you stick to that, it’s pretty easy to get right, and still really useful.
I respectfully disagree. :) I’m all about making people learn more about crypto primitives, but with the ultimate goal of making them aware of the difficulties of handling them securely. I just don’t see any actual benefit of storing your data on the user as opposed to a database. You’re only opening yourself up to more attack vectors without gaining anything.
If your server gets compromised, you’re still paying the same cost as the system needs to be able to access the data. Even worse, if you lose the secret without noticing it, attackers can present fake data to you. A compromised database on the other hand is way easier to detect in comparison. And that secret leakage is not at all far fetched. Secure storage of secrets is incredibly hard. One Bleichenbacher-style vulnerability through an unfortunate error code or a exposed timing difference and a careful attacker might be able to extract the secret without you ever noticing.
One of my declared career goals is never having to touch crypto code in production and so far I’m doing reasonably well at that. :)
Best practices should be reexamined regularly. Agreed.
However, “thinking outside the box” in this fashion is just bad. The “crypto” used in the article is horribly easy to break. There are so many bad ideas in such a short space.
What I’m taking away from this? Never get any software from neosmart.
I would really love to understand how the proposed scheme could be weak. Is it a problem with URI data encoding in general ?
No. This isn’t easy to break, it’s how AWS does signed urls for S3. If you properly keep your secret key, and include information that guards against replay attacks, it’s strong. But with more complex applications come more problems. In these examples, there are a fixed number of keys, but in an optional key situation these can be vulnerable to extension attacks.
To do an extension attack, you add in another field, and continue where the hash left off. Since a hash is an incremental calculation, you can just take the hash and keep mixing in bits. Presumably the extra field is optional, and has some additional meaning your are exploiting. You can protect against this by hashing the content length in as well, and then verifying the content length later. Basically, the more information you include, and hash, and later verify, the less leeway a hacker has to break the scheme.
He’s using HMAC everywhere, so length doesn’t matter. His key/value pairs always have separators, so no game there, too. All requests include time, which gives us defense against replaying and a small protection against guessing. Just add random salt and good luck cracking this.
Ah, that’s correct. I forgot HMAC guards against extension attacks, I was thinking of plain old hashing! So yes, this strategy is pretty secure as is.
Nah, I re-checked the “A Secure Cookie Protocol” paper and he’s gonna leak key info anyway. Separately derived hmac keys are required, too.
OK, people do get this wrong. But telling them to not even try is kind of stupid too.
Care to elaborate on leaking info?
Edit: if you are referring to volume attacks, I doubt an HMAC with a sufficiently strong hash like sha512 would be vulnerable.
I am not sure, thus I prefer to follow the recommendation of the smarter guys. In this case I’d prefer to err on the side of caution and make sure that an attacker only gets to per-user key when spamming some API, generating signatures.
Sadly, I am not a cryptographer.
Just add random salt and good luck cracking this.
He’s mixing in the old bcrypt hash - that’s going to have a per-user salt already. It’s not per HMAC, but I wonder if there’s enough entropy anyway.
Since you mentioned AWS: http://www.daemonology.net/blog/2008-12-18-AWS-signature-version-1-is-insecure.html
I linked AWS signature version 4, which is much newer.
Sorry, my point was this technique has been known to fail in the past. I think any article advocating for crypto cleverness should, in the interest of full disclosure, include some discussion of previous attempts and failures so that people can assess the likelihood they’ll do better.
Yeah, I’m going to have to join mr-foobar and say “show your work!”
I get a sense of unease when I see people going too far off the trail but I’m not sure I see anything that I’d describe as horribly easy to break.
But I’m no crypto expert, just an interested onlooker - the most dangerous person when it comes to cryptography.
See my reply to mr-foobar. It’s definitely not easy to break as is, but even simple modifications can break the scheme in unexpected ways. Only people who are familiar with crypto primitives and their weaknesses should design something like this for real production use.