sean cassidy : When names outlive their usefulness

in: programming

For years I've been using mkpasswd in Linux to generate the occasional password. It seemed like the perfect tool and it was installed nearly everywhere.

The one weird bit was that it prompts you for a password1. Like this:

$ mkpasswd

I just always banged on my keyboard, and I got a random looking password. Certainly good enough for my purposes, right?

It doesn't generate passwords

My friend was recently talking about how he used openssl to generate passwords for databases and things where you don't need to memorize the password. Like this:

$ openssl rand -base64 10

I laughed and asked him why he wasn't using the included utility which does exactly that: make passwords. He told me that mkpasswd actually doesn't generate passwords, it actually generates the hashed and salted password that goes in /etc/shadow.

And he's right.

But "So what," I said, the salt it uses is probably random enough. Probably 32-bits or more, certainly enough for a password. So, I checked:

$ apt-get source whois
$ cd whois*/
$ vim mkpasswd.c

I found this:

static const struct crypt_method methods[] = {
    /* method       prefix  minlen, maxlen  rounds description */
    { "des",        "", 2,  2,  0,
    N_("standard 56 bit DES-based crypt(3)") },
    { "md5",        "$1$",  8,  8,  0, "MD5" },
#if defined HAVE_SHA_CRYPT
    /* */
    { "sha-256",    "$5$",  8,  16, 1, "SHA-256" },
    { "sha-512",    "$6$",  8,  16, 1, "SHA-512" },

So there's at least two methods to generate hashed passwords: the old DES style, and the newer MD5 based style. If you have it enabled, the SHA-256 version could be used. I figured that of course mkpasswd used the newer style, so I was safe. The random salt would be good enough.


What it does

Does it pick MD5 by default? Or even better, pick SHA-256 if it's available?

/* default: DES password */
if (!salt_prefix) {
    salt_minlen = methods[0].minlen;
    salt_maxlen = methods[0].maxlen;                                             
    salt_prefix = methods[0].prefix;

I guess not. It picks DES by default, as that's first in the array.. Which means the salt length is exactly two. How many possibilities does that leave us?

static const char valid_salts[] = "abcdefghijklmnopqrstuvwxyz"

64 for each of the two bytes. This leaves 4096 possibilities for each password you type. And if you don't type any password, like I did at least once, your password is only one of 4096 possibilities.

Here's the list of the 4096 "passwords" if you just press enter at the mkpasswd "Password:" prompt. If these aren't already in a password dictionary I'd be surprised.

Lesson learned: read the manpage. And be careful when choosing a name for your project2. It might outlive its usefulness.

  1. Sometimes. It depends on which version is installed. See the other mkpasswd's manpage

  2. The origin of this simply comes from the fact that it was used to make the /etc/passwd file, which used to contain the hashed passwords before /etc/shadow was created. So it wasn't named poorly then, but it is now. 

Sean is the Head of Security at Asana, a work management platform for teams.

Follow @sean_a_cassidy