I just sold an old hard drive on eBay. Before I could do that I wanted to wipe the drive with random data. I started doing it the usual way by overwriting the whole drive with data from /dev/urandom with dd. Like this:
# dd if=/dev/urandom > /dev/sda
And oh my, was it slow. It took ages. So I wondered, what is the hold up? Is dd so slow? Or is it /dev/urandom? It turns out it was both. To be able to compare it I created a small test partition of 524288000 bytes on /dev/sda1 and took some time measurements. Note that this was an old drive in a really old computer. So the absolute speed is catastrophically slow anyway. I am here just interested in the relative speed differences of different methods.
First the dd way:
stargate:~# time dd if=/dev/urandom > /dev/sda1 dd: writing to ‘standard output’: No space left on device 1024001+0 records in 1024000+0 records out 524288000 bytes (524 MB) copied, 139,46 s, 3,8 MB/s real 2m19.463s user 0m0.516s sys 1m47.979s
Now again by avoiding dd and copying the data straight with cp:
stargate:~# time cp /dev/urandom /dev/sda1 cp: error writing ‘/dev/sda1’: No space left on device cp: failed to extend ‘/dev/sda1’: No space left on device real 1m38.376s user 0m0.012s sys 1m37.226s
Alright. A little bit faster. So cp is a lot faster then dd.
And thanks to the Arch Linux Wiki, here is the super fast way with openssl:
stargate:~# time openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt </dev/zero > /dev/sda1 error writing output file real 0m22.451s user 0m14.929s sys 0m1.476s
So 22 seconds compared to over 2 minutes is quite a nice performance improvement. Note, that dd and /dev/urandom are only used to create a 1024 bit random pass phrase. openssl takes a stream of zeros from /dev/zero and encrypts it with aes-256 and the random pass phrase. The result is basically random garbage. So that way I was able to wipe the whole drive in minutes instead of hours.
If you want a nice progress bar you can also throw in pv like this. Just replace <DISK_SIZE> with the actual size in bytes of the drive you are wiping.
openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt </dev/zero | pv -bartpes <DISK_SIZE> > /dev/sda