Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question
add comment

7 Answers 7

up vote 7 down vote accepted

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./]
share|improve this answer
add comment

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

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

share|improve this answer
add comment

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'.

share|improve this answer
add comment

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.

share|improve this answer
add comment

You could read the source code for the relevant programs, assuming that wouldn't go too far over your head.

Edit: reading my comment after I posted it, I realise it might come across as being condescending..... that's not my intention ;-)

share|improve this answer
add comment

Your question is very related to this question.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.