The most secure passwords are, roughly speaking, long and random sequences that cannot be cracked by means of dictionary or brute-force attacks. This assumes of course, that the passwords are stored in a reasonable way, but that is typically not under the user’s control, so we have to live with that assumption.
Having read a post by Kevin Goodman, I was somewhat inspired to use random passwords everywhere, since they can be generated with almost no effort. I really liked the approach, but there are a few inconveniences that come with it if you take things literally. It was proposed to use
/dev/urandom to generate passwords. The problem (for the paranoid like me) with
/dev/urandom is that it does not meet my standards as a cryptographically secure source for random data. It keeps producing data even if the available entropy is depleted. In contrast
/dev/random blocks the output once the system runs out of entropy. As a result, using the commands as in the post can be painstakingly slow, especially in multi-user environments.
Let us assume that you want to create a random password of length 30 consisting of alphanumeric characters and let us also assume that you want to use
/dev/random as a source. The quoted command would roughly look like
$ cat /dev/random | tr -dc 'a-zA-Z0-9' | fold -w 30 | head -n 1
Try it. It may take twenty minutes to finish. Or an hour. Or longer. Monitor your entropy level with
$ cat /proc/sys/kernel/random/entropy_avail
I know this command also consumes entropy, but even without it you typically run out of patience first. I read of several workarounds to raise the level. The system collects entropy e.g. from hardware noise. Cranking up hard drive activity by issuing
ls -R / seems to be a very popular advice. Furthermore, installing
rng-tools is frequently suggested. I strongly oppose the use of this program, but even if you don’t have an opinion on it, you may not be in the comfortable situation where you can install it. However, if you watch the entropy you will likely encounter values in the range 0-60 or so. That’s the number of bits of entropy available. But how come that the command above doesn’t finish? One may think that those number of bits should be enough to generate a couple of random characters in a way shorter time. Gee, I can take a couple of dice and roll a random password by myself.
The problem lies in the use of
head. They do not really work on data streams in the way we would like them to. They wait until they have read enough data into a buffer (or when the data stream terminates) and then start operating. Unfortunately that buffer is so large that takes too long (for the impatient) to be filled. I couldn’t find out how large exactly the buffers are or which of
head is the bigger one and therefore the bottleneck.
One way out of this is to kill the
cat /dev/random command in another shell. But how elegant is that? Also you have to guess when enough random bytes are gathered.
tr is also the bad guy here in another sense. The option
-dc 'a-zA-Z0-9' drops all bytes that are not alphanumeric. Effectively this discards most of the perfectly good random data. Is there a way to use it? Yes.
Let’s propose a of way to fix this. First, we simply redirect
/dev/random into a file (called
rpwds.txt). In a second terminal we can monitor its size by
ls -l rpwds.txt. When it reaches approximately 30-40 bytes you can terminate the cat command with
CTRL-C. The method to use all random bytes in
rpwds.txt is given by the use of
base64. It basically transforms arbitrary sequences of bits into “human-readable” form. After that the output can still contain the characters
'+/=', which you can then remove with
tr if you want. The output is your random password! Or the first 30 characters of it. After that you are still left with the file
rpwds.txt. Not a good idea to keep it. You should get rid of it safely. This can be done with
Let’s walk through an example. Starting with
$ cat /dev/random > rpwds.txt ^C
which I terminated after a couple of seconds. The file size was
$ ls -l rpwds.txt -rw-r----- 1 username group 232 9 Jun 14:41 rpwds.txt
I gathered 232 bytes, which is more than enough. Now
base64 it, remove unwanted characters and print it in chunks of 30:
$ base64 rpwds.txt | tr -d '+/=\n' | fold -w 30 66OlSO8L7KoW44awcg2xHJ9X1FbOoF 4zcXk1R29WSAJz8TeKYWiMtaPnYQ9M JbJh5PDsBgWCS9CWSg30tbYlhDPHJ9 k3gZo0wIQsVYcW13mRUZdnBEBXd4rG M9EYIFxJJ5pYJf4LV3WWlV9holo9z9 huRQujBdsLIo8BFmGnc4wQk4crvMtS zNPEm6cuUwcbJtmCWQH64pz321zWjt 0h5Z8FcMszELCCJO5hbZ19HKqXGSGG cmR17wGugWSkw9CXjKvrgVEcJIsnpY 3TyCpMJ2EjCrjpbnK8sy3P3m3rGZNh w
Each of those lines (with the exception of the last one) is a nice password. After that
$ shred -n 50 -z -u rpwds.txt
removes all traces (within the scope of
Some final remarks:
More secure passwords contain more special characters. You could keep the
'='s at the end are kind of predictable and do not really add to the security of the password. If you want different characters like
'#!?@$...' you cannot use
base64. Maybe the “kill the
cat” approach mentioned above wasn’t so stupid after all. In any case, having a sequence of 30 random alphanumeric digits is sufficiently safe by today’s standards, and it definitely beats
'password123' and it’s degenerated ancestors.
The obvious question at last: how the hell am I supposed to remember a password like
'66OlSO8L7KoW44awcg2xHJ9X1FbOoF' for every site that I use? Well, if you use some kind of password vault, you will only have to recall only one of the type
'66OlSO8L7KoW44awcg2xHJ9X1FbOoF'. Making a truecrypt container with text files for your other login data can do the trick (assuming truecrypt is trustworthy, well… let’s discuss that on a different occasion). There are a lot of other solutions out there, but I won’t go into details here and reserve that for another post. All other passwords like
'4zcXk1R29WSAJz8TeKYWiMtaPnYQ9M' can be stored inside the vault. Remembering one 30 character password is feasible, I’ve done it a couple of times. Practice typing it and it will become another routine in your life.