What is the quickest way to generate lots of random data on the command line? Usually when I had to wipe hard-drives I would simply use
dd to copy from
/dev/urandom over the device. However, `/dev/urandom is quite slow and wiping hard-disks can take a long time that way. So, I decided to benchmark a few methods to generate long random streams that are usable in such scenarios.
The benchmark is based on the
dd command. For example:
$ dd if=/dev/urandom of=/dev/null bs=4k count=1M
This command will copy a 4GB of random bytes from
/dev/null. This is probably the simplest method to create a large stream of random bytes, and as it turns out, also the slowest.
The second construct I tried is to use OpenSSL to create a stream of random data which I can read with
dd and then write to the target. For example the following would use AES-128 with a random key:
$ openssl rand -hex 32 | openssl enc -aes-128-ctr -in /dev/zero -pass stdin -nosalt | dd if=/dev/stdin of=/dev/null bs=4k count=1M
Let’s breakup this command:
openssl rand -hex 32 will generate a random encryption key to be used by the AES encryption.
openssl enc -aes-128-ctr -in /dev/zero -pass stdin -nosalt does the actual encryption. It reads the (random) key from
stdin and then uses it to encrypt
/dev/zero using AES-128 in counter mode. As
/dev/zero in an endless stream of zeros, it will simply output an endless stream of (pseudo-)random data. We can also repeat the same command only swapping
aes-256-ctr. For most (all?) usage scenarios it doesn’t provided any added security benefits but does have a (small) performance penalty.
Apart from AES, which is a block cipher, we can also try to use actual stream ciphers like the old
rc4 and the modern
Additionally, many new CPUs come with AES-NI extension which speeds up AES operations considerably. We can repeat the benchmark while disabling AES-NI to see how the different methods will perform if used a CPU that doesn’t support AES-NI.
Finally, I’ve repeated the test with
/dev/zero as input, just to have an upper-limit in terms of performance to compare against.
The results clearly show that you should avoid
/dev/urandom. It’s simply not suitable for this task and doesn’t perform well. The various methods of using OpenSSL perform much better. The best performance is achieved by the two AES variants, with
aes-128-ctr being the fastest. However, if AES-NI is not supported by the CPU, AES takes a huge performance hit, and is even slower than the (not-so-)good and old RC4. However, ChaCha20 (a modern stream cipher) performs within 30% of AES if AES-NI is available, but if AES-NI is not supported ChaCha20 outperforms the AES variants. So, unless you know AES-NI is supported ChaCha20 is the safe choice.
2 thoughts on “Quickly generate lots of random data”
why random and not just zero’s or one’s ?
I assume you’re referring to wiping encrypted disks. If you wipe the disk with a known pattern (like zeros or ones) a potential malicous attacker could copy aside the encrypted blocks that resulted from the pattern and replay them in the future to change the plaintext content back to the known pattern.