Both arc4random and /dev/urandom have histories of problems. Some systems have reimplemented arc4random without RC4, but some systems kept RC4. I prefer arc4random over /dev/urandom, but if your goal is to avoid RC4, and you have a system where arc4random uses RC4 and /dev/urandom avoids RC4, then you would prefer /dev/urandom.
These systems have arc4random without RC4:
These use RC4: As of 2017, both DragonFly BSD and FreeBSD kept arc4random with RC4.
These problems can happen with arc4random: Fortunately, none of these problems happen if your system has fixed arc4random.
- arc4random might use RC4.
- arc4random might use an improved RC4 that discards the first few hundred bytes after keying the stream, but it might not discard enough bytes.
- arc4random might fail to detect a fork. After the fork, both processes would get identical random numbers.
- arc4random might fail to get entropy from the kernel, then seed itself using only gettimeofday and getpid, then generate predictable and insecure numbers. In DragonFly BSD and FreeBSD, the sysctl to get entropy should never fail, so arc4random should never reach the code to use only gettimeofday and getpid.
These problems can happen with /dev/urandom: Unfortunately, some of these problems don't have a fix.
- /dev/urandom can use RC4. It did in OpenBSD before 5.5. In most other systems, /dev/urandom never used RC4.
- /dev/urandom might not exist. This might happen inside a chroot. Some setups don't allow device nodes like /dev/urandom inside the chroot.
- The program might fail to open /dev/urandom because it has reached the limit on file descriptors. This might not be a problem if the program doesn't open lots of files, or if it opens /dev/urandom early.
- Multi-core machines might slow down, if multiple cores are reading /dev/urandom, but the kernel uses only core to generate the random numbers. This might not be a problem if you have few cores or don't need too many random bytes.
Because of the last 3 problems (chroot, fd limit, multiple cores), I prefer arc4random over /dev/urandom.
There is a third option: Instead of arc4random or /dev/urandom, you might use a crypto library with a secure random number generator.
GnuTLS uses ChaCha or AES for random numbers. NSS uses SHA-256 for random. OpenSSL seems to be switching from SHA-1 to AES for random. All three libraries (GnuTLS, NSS, OpenSSL) seem to avoid RC4 for random numbers.
LibreSSL might call arc4random and use RC4 in systems like DragonFly BSD. Therefore, you can't trust LibreSSL to avoid RC4.
Some people have spread doubt about random numbers from userspace. These people oppose userspace generators (like arc4random, GnuTLS, NSS, OpenSSL, and OpenSSL again) and prefer /dev/urandom for random numbers. This might have influenced Ruby to prefer /dev/urandom over OpenSSL. I prefer the userspace libraries because of my above list of problems with /dev/urandom.