Tip: Encrypted passwords, just add salt

You can generate encrypted password strings (hashes) using the openssl utility.

You need to supply both a “salt” string and the password you wish to encrypt:

  # openssl passwd -1 -salt MoreSalt ThePassword
  $1$MoreSalt$Cvu.5MdMq1BjAsFp1oc.f/

The following command line generates a random 8-character salt string:

  # openssl rand -base64 6

Combine these into a single command line that uses a different random salt on each invocation:

  # openssl passwd -1 -salt $(openssl rand -base64 6) ThePassword
  $1$XpOpurgQ$41bulzoCV8viFy37EX6jk.

Read on for a comparison between old crypt()-style passwords and the current md5-style shadow passwords.

crypt()-style passwords

  openssl passwd MyPassword
  Warning: truncating password to 8 characters
  QRQHhjukZdgNE

The first 2 characters are known as the “salt”. They add flavor to your password hash – the encrypted string depends both on your password and the salt string, making it more difficult to determine the original password. This is the “old-style” password hashing used by Unix systems.

When logging in, the system basically takes the known salt (from the encrypted password string in /etc/password) and the password you entered. If the hashes match, you’re allowed access:

openssl passwd -salt QR MyPassword
Warning: truncating password to 8 characters
QRQHhjukZdgNE

Yup, the hashes match so you typed the correct password. This system is no longer considered secure:

  • The salt is only 2 characters
  • The /etc/password must be readable by anyone on the system – including an attacker!
  • The password can be only 8 characters long, the rest is discarded
  • The DES crypt() algorithm has a 56-bit keyspace, 2^56 combinations is no longer enough

All possible password variations can be pre-computed, making this system obsolete (Google for “Rainbow tables”).

MD5 passwords

The new mechanism uses “salt” strings of up to 8 characters. The password is hashed using the MD5 algorithm – you can use very long passwords. The keyspace is 128 bits, so there are 2^128 possible combinations. This makes the algorithm orders of magnitude better than the old crypt() (actually, 2^72 times better ;-)).

  openssl passwd -1 -salt $(openssl rand -base64 6) ThePassword

Of course, there are other ways to generate strings of random data. This one reads from a special device file. On Linux, /dev/urandom is a non-blocking pseudo-random number generator (PRNG). This data is then BASE64-encoded to generate an 8-character printable string (this is a property of the MIME BASE64 encoding: the output is 4/3 the size of the input).

  dd if=/dev/urandom bs=6 count=1 | base64