existential type crisis : When names outlive their usefulness

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
Password:

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
IQR5X92MB3wz6zSKfLw=

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
    /* http://people.redhat.com/drepper/SHA-crypt.txt */
    { "sha-256",    "$5$",  8,  16, 1, "SHA-256" },
    { "sha-512",    "$6$",  8,  16, 1, "SHA-512" },
#endif

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.

Right?

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"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";

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. 

Articles

  1. Diagnosis of the OpenSSL Heartbleed Bug
  2. The Intuition Trap
  3. Ambition
  4. The Story of the GnuTLS Bug
  5. Wrong Solutions
  6. Host an infodump session
  7. So, you want to crypto
  8. Hackers and Engineering School
  9. Strings are untyped
  10. Don't Pipe to your Shell
  11. How to Organize Your Brain with Bookmark Tags
  12. You are not a 10x Developer
  13. Windows ruins everything
  14. Don't Give Up and Die
  15. On Being Nice
  16. Bus Factors and Walk Score
  17. Wiggle the mouse to fix the test
  18. A Difficult Bug
  19. The Origins of the Diluvian Network
  20. Zipf your variable names
  21. H.264 and VP8, compared
  22. On Accepting Interview Question Answers
  23. Rate Limiting per User
  24. Write your own Data Structures