For a software, I don't want the user to choose weak keys, so I plan to just read the needed number of bytes from /dev/random to create the needed secret keys. Is it safe to do so?
2 Answers
Yes, in any algorithm where keys are just random numbers, reading them from /dev/random
is safe.
However, /dev/random
blocks if the kernel's entropy estimate goes to zero so it is often a good idea to use a user space CSPRNG seeded from /dev/random
or /dev/urandom
for session keys and other similar random numbers that are used in bulk. The newer getrandom
interface may be preferable when available.
Using /dev/urandom
or getrandom
directly is also fine, when you do not need a high rate of randomness, as they are rather slow (on Linux < 4.8 at least).
-
1$\begingroup$ Additionally, it's worth mentioning that getrandom(2) is a better option, if available on the platform. $\endgroup$ Oct 6, 2015 at 0:11
-
2$\begingroup$ @StephenTouset A userspace CSPRNG is much faster and allows using
/dev/random
which guarantees early boot entropy, butgetrandom
fixes the latter problem and should indeed be recommended. $\endgroup$– otusOct 6, 2015 at 6:50 -
1$\begingroup$ The early boot entropy problem is entirely a non-issue outside of very special-case software. By the time your userspace service has started, there is already plenty of entropy in the kernel. And I'm rather swayed by the argument that userspace CSPRNGs have been a frequently-recurring source of failures in the real world: for example, Debian OpenSSH keys and repeated ECDSA keys in Android bitcoin wallets. $\endgroup$ Oct 6, 2015 at 18:59
-
1$\begingroup$ @StephenTouset, the failed userspace PRNGs have usually been homebrewn and/or failed in entropy collection. Using something simple like CTR-DRBG that gets seeded with kernel entropy is IMO easy to make correct. However, yes, if a low rate of random numbers is needed, even that complexity can be avoided. $\endgroup$– otusOct 7, 2015 at 6:13
-
1$\begingroup$ @forest, yeah that happened after my initial answer, updated. Perhaps worth noting that the designer wrote this in one of the patches to implement that: "The application should have used its own PRNG, but let's try to help it from running, lemming-like, straight over the locking cliff." (Speaking of parallel applications that were starved for urandom output.) $\endgroup$– otusMar 18, 2018 at 7:16
If /dev/random
is working as it should, yes it is safe to generate a key by reading from it; same for /dev/urandom
, which is supposed to be equally safe, and non-blocking, thus always preferable to /dev/random
.
However, in practice, it is very easy to make a port of /dev/random
(or its underlying entropy sources) that seems to work, but does not, and will generate the same output (or output with predictable correlation) running on different devices, especially after precisely the same duration since boot. This is one of several possible root causes allowing some recent attacks, and similar to what allowed that one (another possible cause is home-grown RNGs trying to improve /dev/(u)random
, or worse not using it).
So, in particular in a non-mainstream implementation of /dev/random
and its entropy providers, and especially if the context of use makes it likely that the random generation occurs after a short predictable time since boot, do not rely exclusively on /dev/random
, or /dev/urandom
(which often will collect less actual entropy) without prior review.
Update per otus's comment: In the above I'm thinking of ports on various things with a unix derivative, like embedded development board, set-top box, internet box or appliance, firewall, payment terminal. On mainstream PC linux or unix distributions, especially in user code, I tend to trust /dev/urandom
. I have no informed opinion on Android ports (neither in general, nor the zillions ports to different hardware). Specifically, I'm most worried of the device automatically generating its long-term private key on first boot after setup.
-
$\begingroup$ What do you mean by non-mainstream port of
/dev/random
? Do some distros mess with it? Android? $\endgroup$– otusOct 7, 2015 at 7:01
/dev/random
(i.e. it should be safe unless the implementation is broken). $\endgroup$\0
on average once every 256 bytes. $\endgroup$