7 ms·
The author mentions HMAC at the end. I think HMAC is really an underrated technique. I remember reading Colin Percival's classic Cryptographic Right Answers[0]
by kccqzy 2y ago
The author mentions HMAC at the end. I think HMAC is really an underrated technique. I remember reading Colin Percival's classic Cryptographic Right Answers[0] and saw a section about "symmetric signatures." I pondered to myself what scheme I could use for that before I looked at the answer: of course it's just HMAC. I feel like this is another perspective that ought to be more widely known: if you want something to be like a signature, but the two parties (or just a single party at different times) can share a key, HMAC really is the right answer. Things like, a server needs to cryptographically sign a cookie to prevent tempering: that's HMAC. Or a server needs to know an API request is coming from an expected client: that's also HMAC.
[0]: https://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html https://www.daemonology.net/blog/2009-06-11-cryptographic-ri...
- anyfoo 2y agoYeah, if you have a shared secret, HMAC is the way to go. It's also super simple: It's almost literally just concatenating the secret and the message you want to authenticate together, and take an ordinary hash (like SHA256) of that, the rest of it is just to deal with padding. It's super intuitive how HMAC works: If you just mash secret and message together on your side, and get the same answer as what the other side told you, then you know that the other side had the secret key (and exactly this message), because there's obviously no way to go from SHA256 to the input. HMAC is also useful if you want to derive new secret keys from other secret keys. Take an HMAC with the secret key and an arbitrary string, you get a new secret key. The other side can do the same thing. Here's the kicker, the arbitrary string does not have to be secret to anyone, it can be completely public! Why would you do that? Well, maybe you want the derived key to have a different lifetime and scope. A "less trusted" component could be given this derived key to do its job without having to know the super-secret key it was derived from (which could be used to derive other keys for other components, or directly HMAC or decrypt other stuff).
- loeg 2y ago> It's also super simple: It's almost literally just concatenating the secret and the message you want to authenticate together, and take an ordinary hash (like SHA256) of that, the rest of it is just to deal with padding. It's not quite as simple as that. The output of the first hash is hashed a second time (to prevent length extension attacks).
- anyfoo 2y agoThanks, forgot to mention that. Needless to say, I always consult real cryptographers when working on stuff like that.
- loeg 2y agoDo you ever need to implement an HMAC from scratch? I'd look for an off-the-shelf solution before trying to find a cryptographer.
- anyfoo 2y agoI don't, and I absolutely did not mean to imply that anyone should implement HMAC themselves. I was addressing people who want to potentially use HMAC (after proper consultation with cryptographers), for which a general understanding of HMAC is prerequisite. Hence why my original comment only described implementation on a surface level, but elaborated over potential uses for HMAC. Only cryptographers should implement crypto primitives. Even if I'd get the algorithm itself right, I might not know how to make it so that it runs in constant time (which is something that crosses into the CPU's ability to do so), and thus may inadvertently leak secrets through side channels. But even if I just use HMAC, I still consult with cryptographers to make sure my use is correct, that there is no better solution, and that I am not missing any attack vectors. Even in simple cases it can be a grave mistake to use seemingly simple crypto primitives without proper consultation, see for example some of the very prominent problems that were the result of improper IV usage with AES.
- resonious 2y agoA bit of a tangent. This isn't a dig on HMAC itself, but using HTTP request body or query string as the HMAC "message" is the worst. My employer provides some APIs with that sort of scheme and it's a very common source of technical customer support tickets. The problem is that many people are using web frameworks that automatically turn body and query into some kind of hash map data structure. So when you tell them "use the request body as the HMAC message", they go "OK, message = JSON.stringify(request.body)", and then it's up to fate whether or not their runtime produces the same exact same JSON as yours. Adding a "YOU MUST USE THE RAW REQUEST BODY" to the docs doesn't seem to work. We've even had customers outright refuse to do so after we ask them to do so in the "why are my verifications failing" ticket. And good luck if it's a large/enterprise customer. Get ready to have 2 different serialization routines: one for the general populous, and one for the very large customer that wrote their integration years ago and you only now found out that their runtime preserves "&" inside JSON strings but yours escapes it. Rant over...
- Elucalidavah 2y ago> "&" inside JSON strings but yours escapes it What escaping of "&" inside JSON are you talking about? Some unholy mix of JSON and urlencode?
- resonious 2y agoRuby on Rails turns "&" into "\u0026". See rails/rails, activesupport/lib/active_support/json/encoding.rb.
- growse 2y agoI think AWS SigV4 tries (and succeeds?) in solving this issue?
- beeboobaa3 2y agoShitty software developers will always find ways to screw things up unfortunately
- __MatrixMan__ 2y agoAre things like Diffie Hellman generally available such that you can always get a symmetric key? Or is that a special case?
- vogr 2y agoI'm no cryptographer, but I would say that it is indeed the case that you can assume that two parties can derive a shared key over an untrusted channel. The post Cryptography Right Answers PQ [1], linked in another comment, addresses this in the section "Key Exchange". Rather than thinking about Diffie-Hellman directly, you would turn to a Key Exchange Mechanism (KEM). Before post-quantum cryptography concerns, KEM were indeed mostly built on top of Diffie-Hellman key agreement, but you could also build one on top of RSA, or on top of some lattice constructs. But you wouldn't build one yourself, there are good constructions to choose from! The OP actually has a 3-part series on KEMs, although I don't think it addresses post-quantum issues [2]. [1]: https://www.latacora.com/blog/2024/07/29/crypto-right-answers-pq/ https://www.latacora.com/blog/2024/07/29/crypto-right-answer... [2]: https://neilmadden.blog/2021/01/22/hybrid-encryption-and-the-kem-dem-paradigm/ https://neilmadden.blog/2021/01/22/hybrid-encryption-and-the...
- nmadden 2y agoJust want to point out that the article specifically says to use an authenticated KEM (AKEM). A normal, unauthenticated KEM would not work as it provides no authentication. There are no post-quantum authenticated KEMs as yet.
- namibj 2y agoThere are post quantum KEMs though that authenticate with a classical mechanism, which limits quantum attacks to interactive from the previous total breakage of recorded ciphertext exchanges (e.g. Wireshark capture at a router encountered in both directions of the traffic flow).
- nmadden 2y ago
- loeg 2y agoMore generally, a MAC. You don't necessarily need one based on a hash. (Unrelated) see also the more recent https://www.latacora.com/blog/2018/04/03/cryptographic-right-answers/ https://www.latacora.com/blog/2018/04/03/cryptographic-right...
- kccqzy 2y agoAh yes of course in 2018 it's still HMAC.
- JimDabell 2y agoThey published a followup to that article two months ago, and the correct answer in 2024 is still HMAC. https://www.latacora.com/blog/2024/07/29/crypto-right-answers-pq/ https://www.latacora.com/blog/2024/07/29/crypto-right-answer...
- tptacek 2y agoWho's "they"? This "right answers" thing is a meme (I ruefully share responsibility for it) that needs to die; Colin Percival has nothing to do with anything but the first one.
- loeg 2y agoI linked to the older Latacora one upthread and this comment is linking to the newer Latacora one. So I think it's reasonable to read "they" as "Latacora" here.
- tptacek 2y agoYes, I wrote the older Latacora one, which was based on thing I wrote under my own name before I founded Latacora; I'm pretty sure I'm on solid ground saying Colin Percival had nothing to do with anything I wrote, since I wrote the first one as a rebuttal to Colin. (Did I misread you? Maybe we just agree.)
- atoav 2y agoOne question I always wondered about with cookie signing is: Why not store the user and the cookie in a database and check against that when they try to present it to you? Performance reasons?
- argulane 2y agoIt's mostly about performance. If you can store all the required info about the user inside the cookie then you can avoid a DB query roundtrip before sending a response. Now that your cookie looks like this (probably also base64 encoded): {"id": 42, "display_name": "John", "is_admin": false, "session_end_at":1726819411} You don't have to hit the DB to display "Hi John" to the user and hide the jucy "Admin" panel. Without HMAC, an attacker could flip the "is_admin" boolean in the cookie. You could also create a cookie that is just random bytes F2x8V0hExbWNMhYMCUqtMrdpSNQb9dwiSiUBId6T3jg and then store it in a DB table with similar info but now you would have to query that table for each request. For small sites it doesn't matter much and if it becomes a problem you can quite easily move that info into a faster key-value store like Redis. And when Redis also becomes too slow you are forced to move to JSON Web Tokens (JWT) witch is just a more standardized base64 encoded json wrapped with HMAC to avoid querying a database for each request. But even if you are using random bytes as your session identifier, you should still wrap it in a HMAC so that you can drop invalid sessions early. Just for making it harder for someone to DDOS your DB.
- kd5bjo 2y agoBack in the Justin.tv days, we used this for some messages that were passed by the client between two of our systems: The main authentication was done by the web stack which gave the client an HMAC-signed viewing authorization. That was then passed on to the video servers which knew how to check the authorization but weren’t hooked up to the main DB. Setting things up this way meant that we didn’t need to muck about with the video server code whenever we made policy changes as well as isolating the video system from web stack failures— If the web servers or DB went down, no new viewers could start up a stream but anyone already watching could continue uninterrupted.
- atoav 2y ago
- arianvanp 2y agoAnd this is is why I have come to love AWS Sigv4