11

I'm learning about Linux password security (more curiosity than anything useful), and I understand that the real password is hashed and stored in the shadow password file. What I'm not sure of, and haven't been able to find in my brief Googling, is what encoding is used to encode the hashed value (and the value of the salt). It's obviously not hex, and it's obviously text, excluding the : character. Can anyone here tell me what that encoding is?

Edit: I'm understand the hashing (MD5, SHA-X), the salt, and the hashing specifier. What I'm looking for is the method of converting the hash results (a byte array (byte[])) to the sequence of characters I see in the file, ie: the encoding.

C. Ross
  • 2,995
  • 8
  • 32
  • 36
  • Use the source: http://sourceware.org/git/?p=glibc.git;a=tree;f=crypt – James Nov 26 '09 at 23:49
  • Your question is very related to [this question.](http://serverfault.com/questions/87874/how-should-someone-create-an-encrypted-password-for-etc-shadow) – Broam Nov 25 '09 at 20:10

4 Answers4

11

In the case of MD5 crypt(), the salt is just a random string of up to 8 characters from [a-zA-Z0-9./].

The salt and password are then hashed together, passed through a strengthening function, then encoded using a variant on Base64:

  • the MD5 state (128 bits) is shuffled up and broken into 6 groups, each containing 3 bytes (the final group includes 2 bytes of zero-padding)
  • each group of 3 bytes is then split into 4 blocks of 6 bits each
  • finally, each 6-bit group is mapped to a character in the range [a-zA-Z0-9./]
SimonJ
  • 741
  • 3
  • 9
9

If you only want to know how the password is encoded, crypt() uses a special Base64-type of encoding.

Base64 encoding uses the following charset: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

While the crypt() encoding uses this charset: ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Also, unlike Base64 there is no "=" padding.

On the other hand, the crypt() implementations of MD5, SHA-X, etc do more than just generate a random salt, run the hash function and encode it using the former encoding.

I recommend reading these two great posts: "Password hashing with MD5-crypt in relation to MD5" and "Implementation of SHA512-crypt vs MD5-crypt", for a more complete explanation.

Marco
  • 191
  • 1
  • 1
4

The first part of the hash in between the $'s indicates what algorithm is being used.

Check out http://en.wikipedia.org/wiki/Crypt_%28Unix%29 for a list of the what the different values mean.

3dinfluence
  • 12,409
  • 2
  • 27
  • 41
2

Are you looking for the algorithm used?

Traditionally Unix and early Linux variants used a weakened DES based on a maximum of 8 characters of the password. Most modern Linux installs use MD5 hashes for the passwords, and some support SHA. Additionally, more modular support for additional algorithms has shown up, including Blowfish. The GNU libc used by most Linux's supports DES, MD5, and SHA, giving you a couple of options.

The specific type of hash algorithm used is specified as the beginning of the password as $DIGIT$. For example, $1$ is MD5.

You can get more in depth details from Wikipedia (see the page on Crypt_(Unix)) or google for 'crypt unix' or 'crypt linux'.

Christopher Cashell
  • 8,999
  • 2
  • 31
  • 43