[HN Gopher] A few secure, random bytes without `pgcrypto`
       ___________________________________________________________________
        
       A few secure, random bytes without `pgcrypto`
        
       Author : surprisetalk
       Score  : 41 points
       Date   : 2024-09-24 21:49 UTC (4 days ago)
        
 (HTM) web link (brandur.org)
 (TXT) w3m dump (brandur.org)
        
       | mhio wrote:
       | gen_random_uuid() produces a v4 UUID.
       | 
       | Taking the first 5 bytes of a v6 UUID (time) and last 5 (node)
       | would be a bad random day.
        
         | manwe150 wrote:
         | Wait, is this blog actually about how to introduce a backdoor
         | into your Postgres install by rolling your own very bad rng?
        
           | fanf2 wrote:
           | No, a v4 uuid comes from a good RNG. The blog post just said
           | v6 by mistake when it meant v4.
        
             | hinkley wrote:
             | V6 is just a v4 rearranged to behave more like v7 for the
             | purposes of b-tree insertion.
        
               | dwattttt wrote:
               | I believe V6 is a reordering of V1, not V4. V4 is random
               | aside from the bits specifying version & variant, ~6/7
               | bits.
        
           | thadt wrote:
           | Nah, mhio is saying that the blog post has a typo:
           | 
           | > Postgres 13's gen_random_uuid() which generates a V6 UUID
           | that's secure...
           | 
           | gen_random_uuid gives you a version V4 UUID, not a V6 UUID
           | (it's even in the code comments in the snipped included in
           | the blog). I don't believe Postgres even _has_ a function to
           | generate a V6 UUID - which, indeed, would be a bad idea to
           | use as a source of randomness.
        
         | hinkley wrote:
         | I read this exact reply on this exact article two days ago.
         | 
         | What is happening right now?
        
           | tom_ wrote:
           | Take the blue pill, press the back button, and pretend you
           | never saw it.
           | 
           | Or take the red pill, pull back the curtains of reality, and
           | see the machinery behind:
           | https://news.ycombinator.com/item?id=41197775
        
         | hinkley wrote:
         | I read this exact reply on this exact article two days ago.
         | 
         | What is happening right now? Why is your comment marked four
         | hours ago?
        
       | davidfiala wrote:
       | Exercise extreme caution.
       | 
       | Having your security strategy rely on quirky behaviors of an
       | implementation detail which might change is incredibly dangerous.
        
         | hinkley wrote:
         | UUID v6 isn't going to change. There's a reason we have seven
         | of them now. And v8, which _would_ warrant your warning.
        
           | poincaredisk wrote:
           | UUIDv6 won't change, but what about gen_random_uuid()
        
             | masklinn wrote:
             | gen_random_uuid isn't going to change either, the entire
             | point is to generate a secure uuid4. At most it'll get
             | faster due to using platform-specific syscalls.
        
             | creatonez wrote:
             | There is widespread acceptance nowadays that randomized
             | UUIDs must be generated from the system CSPRNG or something
             | equivalent, and that any non-cryptographically secure
             | method is a bug. Most library implementations across
             | languages have converged on this in some way.
             | 
             | That being said, the PostgreSQL documentation doesn't say
             | anything in particular about the predictability of
             | `gen_random_uuid`, so the behavior is unspecified. But it's
             | worth noting the function has an explicit guard to raise an
             | error if secure random is not available, so they were
             | conscious of this possibility and did not attempt any
             | misguided fallbacks.
             | 
             | And unfortunately this requirement is not baked into the
             | UUID spec either, which uses the word "should" instead of
             | "must" when discussing CSPRNG usage.
        
         | yunohn wrote:
         | Not everything is a quirky implementation detail? It's
         | important for us developers to not write pure glue code between
         | others functions, but to also understand them and write our
         | useful code that may extend others work.
        
       | hinkley wrote:
       | If you're shopping for a CSPRNG, one of the items that should be
       | very high on your list is being able to call the setSeed function
       | multiple times and have the inputs compose instead of clobber
       | each other.
       | 
       | You can send half-random input in and then send _more_ half-
       | random input in until you're satisfied that the RNG has gotten a
       | suitable amount of entropy. Do not chop, rearrange, hash, or bit
       | shift the data trying to make it "stronger" the CSPRNG will do an
       | infinitely better job of doing that for you. Just treat it like a
       | Mr Fusion. Drop a can, a banana peel and the stale beer in and
       | let it cook.
       | 
       | I gave a similar speech to a team trying to initialize SSL
       | sessions on an embedded machine. "But what if we XOR..." No.
       | Stahp.
        
         | ronsor wrote:
         | Can you give some examples of CSPRNG implementations that allow
         | this?
        
           | andreareina wrote:
           | The Linux rng allows writing to a file to effect this.
        
           | hinkley wrote:
           | The ones in Java did in the context of the original
           | discussion. And cryptographic hash based PRNG should have the
           | capability of doing so, it's an implementation detail whether
           | you restart the data collection or append the data.
           | 
           | Just poke in the setSeed function and see what it does.
        
         | ynik wrote:
         | > You can send half-random input in and then send more half-
         | random input in until you're satisfied that the RNG has gotten
         | a suitable amount of entropy.
         | 
         | This does not actually work. If an attacker can observe output
         | of the CSPRNG, and knows the initial state (when it did not yet
         | have enough entropy), then piecemeal addition of entropy allows
         | the attacker to bruteforce what the added entropy was. To be
         | safe, you need to add a significant amount of entropy at once,
         | without allowing the attacker to observe output from an
         | intermediate state. But after you've done that, you won't ever
         | need to add entropy again.
        
           | beng-nl wrote:
           | You're right, but I did not read GP to suggest otherwise.
           | 
           | GP does not suggest using the output before enough entropy
           | had been gathered, eg see 'until' in:
           | 
           | > until you're satisfied that the RNG has gotten a suitable
           | amount of entropy.
        
           | hinkley wrote:
           | Sibling already answered this. I don't know how you came to
           | this conclusion.
        
         | yunohn wrote:
         | AFAIU the blog author is taking the correctly randomly
         | generated UUID and just cutting out the timestamp portion.
         | 
         | Why are you equating that to a hacky attempt to make less
         | random data more random?
        
           | hinkley wrote:
           | Because it's essentially setSeed(getTimeMillis()). V6 and v7
           | are sortable, that's why they exist. Which means like
           | getTimeMillis() there are a finite number of starting points
           | to try to guess the seed.
        
             | yunohn wrote:
             | This is v4.
        
               | hinkley wrote:
               | v6 is a transform of v1 UUIDs to behave like v7 keys with
               | respect to database indexing - increasing over time. If
               | it's a function of time, then it's still guessable by
               | brute force.
               | 
               | Another responder suggested that the mention of v6 UUIDs
               | is an error. Maybe. But that's a truly bizarre typo to
               | make. And they still haven't fixed it.
        
               | yunohn wrote:
               | But you could google Postgres UUID and confirm that they
               | only provide v4? Instead of continuing a rant based on
               | incorrect assumptions.
               | 
               | https://www.postgresql.org/docs/current/functions-
               | uuid.html
        
         | amenhotep wrote:
         | You seem to be saying that
         | 
         | setSeed(0); setSeed(1); rand()
         | 
         | and
         | 
         | setSeed(1); rand()
         | 
         | returning different values is not only a good idea but _is
         | already a thing_. Am I wrong?
         | 
         | This would confuse the hell out of me, what specifically has
         | this behaviour?
        
           | hinkley wrote:
           | If you're trying to create a repeatable source of randomness
           | for unit testing for example, you would create a new PRNG for
           | each run, not try to recycle an existing instance. You're
           | making assumptions about state that aren't supportable.
        
             | Dylan16807 wrote:
             | The behavior you are describing is not setting a seed. A
             | seed should wipe out all existing state.
             | 
             | Adding entropy is a very different operation.
        
       ___________________________________________________________________
       (page generated 2024-09-28 23:00 UTC)