[HN Gopher] "YOLO" is not a valid hash construction
       ___________________________________________________________________
        
       "YOLO" is not a valid hash construction
        
       Author : ssklash
       Score  : 74 points
       Date   : 2024-08-21 13:53 UTC (3 days ago)
        
 (HTM) web link (blog.trailofbits.com)
 (TXT) w3m dump (blog.trailofbits.com)
        
       | krackers wrote:
       | A cryptography course should be mandated in the curriculum of
       | most universities, just so people gain some intuition about the
       | types of attacks that are possible. Just yelling "don't roll your
       | own crypto" isn't practical advice when most issues come from
       | misusing primitives or combining primitives in a "weak" manner.
        
         | tialaramex wrote:
         | Do you have any hard evidence that somehow mandating a
         | "cryptography course" fixes this?
         | 
         | My guess is that it doesn't help and might even make things
         | worse because now they'll think "Don't roll your own" was an
         | instruction to plebs who didn't take that one semester
         | cryptography course at school.
        
           | reubenmorais wrote:
           | The cryptography course in my bachelor's was good enough to
           | paint a picture of the complexity involved. By then I had
           | already heard the "don't roll your own crypto" mantra, so
           | maybe that primed me, but the semester course helped to get
           | an appreciation for the subtle ways information leaks when
           | you try to contain it. It also gave me some more confidence
           | to push back if for example a colleague tried to convince me
           | that the mantra doesn't apply to them/us.
           | 
           | Obviously you can't mandate a high quality course into
           | existence, but I definitely good value out of having it in
           | the required curriculum.
        
           | plorkyeran wrote:
           | My primary takeaway from the cryptography course I took was a
           | good understanding of _why_ I shouldn 't try to roll my own
           | crypto, but a lot of that came down to the course design.
           | Mine spent significantly more time on covering how various
           | cryptography schemes were broken than on how to implement
           | things, and a course which was the other way around could
           | easily inspire false confidence.
        
         | withinboredom wrote:
         | I've seen crypto papers (and cited!) that are worse than this
         | advice. Not sure what you are trying to say here.
        
         | axoltl wrote:
         | Speaking as someone that has both broken crypto systems and
         | designed ones that got broken (internally, in review, before
         | they made it out), it takes a lot of practice to become
         | proficient at cryptography. Sometimes a little bit of knowledge
         | is worse than none at all.
        
       | playingalong wrote:
       | The article is not that different than "don't invent your own
       | cryptography".
       | 
       | It's hard to understand for non-crypto specialists. It uses
       | notions which are unknown to most programmers like MAC or other
       | *MACs.
       | 
       | So not sure who is the target audience for this.
        
         | olliej wrote:
         | It is essentially "don't roll your own crypto", but instead
         | being screeds of complexity it just highlights a few very basic
         | and simple things that seem "obviously fine" to folk that are
         | unfamiliar (eg doesn't touch on any complex reasons for it
         | being bad, and doesn't just say "you're stupid"). It then gives
         | examples of these basic problems causing real world failures,
         | and it then just says "this is what you should use instead".
         | 
         | Eg it's very to-the-point, doesn't spend all its time talking
         | about how the professionals are awesome and better than you,
         | and gives actionable recommendations. Most "don't roll your own
         | crypto" articles don't do that and just come off as being
         | elitist, and don't actually _help_ the reader.
        
         | tptacek wrote:
         | Trail runs a cryptography practice that does assurance work for
         | cryptography engineers. They're not writing to encourage
         | randomly-selected HN readers to design their own cryptosystems.
        
         | yarg wrote:
         | It was simple enough for me as a non-crypto guy - in fact, it
         | seemed mostly obvious.
        
       | tptacek wrote:
       | This is a good post, but there's a little too much ritual in here
       | about password-based KDFs for my taste. Put all the mainstream
       | KDFs on a dartboard, yes including PBKDF2, and throw a dart. I
       | think you'll be fine. Bcrypt, the most popular password hash, has
       | held up surprisingly well, and scrypt might still be one of the
       | best options.
        
         | Vecr wrote:
         | There's no point intentionally making your implementation
         | weaker than it has to be.
        
           | delusional wrote:
           | The complement is also true. There's no point in making it
           | stronger than it has to be.
           | 
           | If I have this box that says Bcrypt, but scrypt might be
           | better. I can either spend a bunch of time re-implementing
           | scrypt, or I can shove Bcrypt into there and move on. If
           | Bcrypt is sufficient, then I don't really care if scrypt
           | would be "better"
        
             | Vecr wrote:
             | I think tptacek is talking about a ground-up design, in
             | that case I think you should use Argon2id. Using something
             | weaker is not really needed, turn the parallelism down to 1
             | and then start reducing the rounds and memory until it
             | works for your case.
        
               | tptacek wrote:
               | I would probably still reach for scrypt.
        
               | Aachen wrote:
               | The LUKS2 source code mentions there is an attack on
               | Argon2 which they prevent by setting rounds to 2 or 4
               | iirc. Not sure what that's about though, would need to
               | look it up again but perhaps heed the recommended
               | settings to avoid such pitfalls
               | 
               | As for parallelism=1, why would you do that? My
               | understanding is that you want it to a point where it'll
               | saturate your memory bus because then you're getting the
               | most out of your system -> making it the hardest for the
               | attacker. (Pretty sure this takes more than one thread on
               | a modern system because I've tested that argon2id with
               | the same number of rounds and memory gets faster with
               | more threads.) Beyond that, increasing memory usage is
               | good because that dominates the die space of an ASIC
               | which in turn dominates the cost, if I remember and
               | understood the argon2 paper correctly. The repetitions
               | value is the last thing to touch, namely when you've run
               | out of threads and usable RAM (such as when it gets into
               | DoS territory)
               | 
               | (I focus on argon2 because that's what I've read up on.
               | Scrypt is also a good option but I'm not sure the same
               | advice applies because it has this TMTO attack. The
               | underlying concepts will be the same of course, but
               | tweaking one parameter before another may play into the
               | attacker's hand.)
        
               | Vecr wrote:
               | No. The parallelism is an upper bound, higher reduces
               | security. If you're running a server for multiple clients
               | each client should only get one thread for argon2 anyway,
               | more won't help your overall throughput.
        
         | vintermann wrote:
         | Yes, it was conspicuous to me that for the two other examples,
         | they mentioned "this has been used in a real attack!", but for
         | key derivation functions, they didn't say that.
         | 
         | Sure, you should still use Argon2.
        
         | Aachen wrote:
         | Still a difference between "you'll be fine" and "if you're
         | newly choosing, might as well _not_ pick PBKDF2 where anyone
         | with a regular GPU gets a 100x speedup compared to your server
         | CPU ". Bcrypt wasn't even designed for memory hardness but is
         | so much more annoying to crack because it seems to stress (per
         | my understanding) the GPU's memory bus _just_ enough with the
         | iirc 4k state table that 's being randomly accessed
        
           | layer8 wrote:
           | In the browser, PBKDF2 can still make sense, because all
           | modern browsers support it via _SubtleCrypto.deriveKey()_ ,
           | and you may want to avoid the overhead of a JS-implemented
           | alternative. Just select the maximum iteration count that is
           | still acceptable for your use case and targeted devices
           | (mobile devices tend to be the slowest).
        
             | Aachen wrote:
             | Very true. May make sense to check how WASM implementations
             | stack up, though. Makes me realise I don't even know if
             | WASM does multithreading; maybe via background workers?
        
         | FreakLegion wrote:
         | I'd draw a line at the post's NIST-adjacent advice.
         | 
         | With the caveat that I may be up to two years out of date here:
         | Last I checked Balloon was a bad choice (only a research
         | implementation) and Argon2 didn't meet the requirements
         | (unapproved primitive in BLAKE2).
         | 
         | With enough rigamarole can you get these into a government
         | office? Probably. But scrypt and yescrypt (the default on most
         | Linux systems) already fit the bill, so just use one of those.
        
       | trainofbit wrote:
       | The RFC recommendation for 1G RAM or 64MB Argon PKDF is insane.
       | Don't follow this advice. In a real world server, any API
       | endpoint using this advice will quickly become a DOS vector. A
       | saner value is 1MB for Argon. It stills blocks major GPU attacks,
       | which is the whole point.
        
         | galdor wrote:
         | OWASP recommendations for Argon2id are 19MiB memory, iterations
         | 2, parallelism 1. And following OWASP is not only a good idea
         | for security but also makes it easy to justify with IT
         | security, compliance, etc.
        
           | tptacek wrote:
           | It's been a little while since I've looked carefully but I
           | would not take OWASP especially seriously on matters of
           | cryptography. It helps to understand that OWASP is more of an
           | affinity group than a carefully structured authority, and
           | some of its official recommendations are more akin to wiki
           | pages than real standards.
        
         | Dylan16807 wrote:
         | You have to be careful to toss around gigabytes, but what's
         | unreasonable about 64MB? You should only be running about one
         | per core, right?.
        
       | theamk wrote:
       | It's interesting that using JSON encoding for all messages
       | eliminates many of the problems.
       | 
       | ambiguous encoding? Nothing ambiguous about JSON, you don't even
       | need any separator. Or merge them into json array.
       | 
       | length-extension attacks? appending non-whitespace to json makes
       | it invalid (for sane decoders at least)
        
         | skybrian wrote:
         | Yes, but there are lots of way to get different encodings (and
         | therefore hashes) for the same data: whitespace, JSON object
         | key order, and the different ways of escaping characters.
         | 
         | If you want a _unique_ hash (like, for a hash table lookup)
         | then you 'll need to sort the keys of every object and use a
         | particular implementation of JSON.stringify.
         | 
         | (Also, what do you mean by "you don't even need any
         | separator?")
        
           | magicalhippo wrote:
           | XML has a complex solution for this, canonicalization[1], to
           | enable signed XMLs[2]. Seems some folks are trying the same
           | with JSON[3].
           | 
           | [1]: https://en.wikipedia.org/wiki/Canonical_XML
           | 
           | [2]: https://en.wikipedia.org/wiki/XML_Signature
           | 
           | [3]: https://www.rfc-editor.org/rfc/rfc8785
        
       | Dylan16807 wrote:
       | > While Keccak doesn't suffer from the length-extension attacks
       | that HMAC is meant to address, the phrase "simply prepending the
       | message with the key" carries a lot of assumptions about key
       | length and key formatting with it.
       | 
       | A _lot_ of assumptions, or just that it 's fixed length?
        
         | adgjlsfhk1 wrote:
         | also that the key is never used for anything else (which could
         | allow for unintentional collisions)
        
       | layer8 wrote:
       | > The issue we run into here is ambiguous encoding.
       | 
       | What I have done in the past for this is to encode the messages
       | as UTF-8 and separate them by 0xFF, since that byte value never
       | occurs in UTF-8 encoding [0]. If the messages to be hashed are
       | character strings, you have to decide on _some_ encoding anyway
       | in order to hash them.
       | 
       | [0] UTF-8 bytes always contain at least one zero bit:
       | https://en.wikipedia.org/wiki/UTF-8#Encoding. Incidentally, if
       | one wanted to create the UTF-8 equivalent of zero-terminated
       | strings without reserving a character value (like NUL) as the
       | sentinel value, one could use 0xFF for that.
        
         | dfox wrote:
         | That actually makes more sense than the usual opposite approach
         | of using over-long encoding for NULs in the data.
        
       | blauditore wrote:
       | I'm no expert and a bit tired, but: Is the problem around hashing
       | password + salt for a key just about the fact it can be brute-
       | forced with enough recources, or did I miss something?
        
       ___________________________________________________________________
       (page generated 2024-08-24 23:00 UTC)