21

I'm using Postgres's uuid_generate_v4 in a uuid primary key column to generate secure one-time authentication tokens. Is this okay? Does Postgres use a secure random number source for generating these UUIDs or should I be generating them using a securely random source on the application-side before inserting them into the database?

Anders
  • 64,406
  • 24
  • 178
  • 215
glittershark
  • 313
  • 2
  • 6

1 Answers1

23

The PostgreSQL documentation says that UUID generation relies on the OSSP library. A look at the source code of OSSP (version 1.6.2) shows that the code uses /dev/urandom on Unix-like systems (CryptGenRandom() on Windows), and also a much weaker PRNG based on current time, process ID, and the C library rand() function. Fortunately, the two outputs are XORed together, so the use of /dev/urandom is sufficient to guarantee strong randomness, regardless of how weak the other PRNG may be. Unfortunately, if the opening of /dev/urandom fails for any reason (e.g. the process had run out of free file descriptors at that moment), the library falls back to using the weak PRNG only, with no warning.

Therefore, while v4 UUID generated by PostgreSQL should usually include 122 bits of cryptographically strong randomness, there is always a possibility of degradation into a much weaker behaviour, with no reliable method to test for that occurrence. Also, none of this seems really documented, so it may change in other library versions. Therefore, caution advises not to rely on the strong randomness of UUID generated by PostgreSQL, and instead explicitly use a strong random source on the application side (typically /dev/urandom, but not hiding access errors).

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 1
    I just want to draw some attention to "F.43.2. Building uuid-ossp" [here](http://www.postgresql.org/docs/9.5/static/uuid-ossp.html), which says that uuid-ossp can now be built without the OSSP library on some platforms using Libc and/or Libuuid. The site also says at the bottom: "Note: If you only need randomly-generated (version 4) UUIDs, consider using the gen_random_uuid() function from the [pgcrypto](http://www.postgresql.org/docs/9.5/static/pgcrypto.html) module instead." – Mrtn Jul 14 '15 at 14:21
  • Isn't `/dev/urandom` the bad one ("unblocking random") and `/dev/random` the good stuff when it comes to random stuff? I thought `urandom` was just a PRNG on the other end... – Alec Teal Jul 14 '15 at 20:30
  • @AlecTeal: no, that's the other way round. `/dev/urandom` is the good one; `/dev/random` output is equally good, but not "better", and `/dev/random` is often cranky and blocks. See [this page](http://www.2uo.de/myths-about-urandom/) for nice explanations. – Thomas Pornin Jul 14 '15 at 20:32
  • 1
    @ThomasPornin, the "arguing with the reader" format that page uses is tiring to read, but it appears to omit the one situation when blocking is good: if entropy is genuinely low (think: first power-up of an embedded device). – Mark Jul 14 '15 at 22:26