I was expecting slappasswd to produce a fixed hash but it appears that the output is randomized as I never get the same output for the same input password:

$ slappasswd -s secret
$ slappasswd -s secret
$ slappasswd -s secret

During authentication, how does slapd knows how to randomize the hash for the provided password in the same way so that it can match the password defined in the first place?


Going out on a limb here, but I assume slappasswd is using a salted hash instead of a plain hash. This means that it adds a random prefix to your password, and saves that random prefix as part of the string you see in the slappasswd output. When you type your password, it adds the prefix to it, hashes the result and compares that to the string in the slappasswd output. If it matches, you are in. If it does not, you password was wrong :)

| improve this answer | |
  • 3
    Indeed. In particular, the default hash method for slappasswd is {SSHA}, or the salted version of SHA-1. – justarobert Apr 15 '11 at 9:42
  • I agree, but my question remains: if the salt ends up as part of the hash that means you can't extract the salt from the hashed password. Accordingly how does slapd knows what salt to add when doing the password verification? (it has to add the same salt for the hashed passwords to be the same). – Max Apr 15 '11 at 10:23
  • 3
    @user: The part after {SSHA} contains both the salt and the hash. – user1686 Apr 15 '11 at 14:58

SSHA is a salted SHA-1. By default the last 4 Bytes are the salt. The output of slappasswd is

'{<Hash Method>}<base64 converted hash and salt>'

So in order to test, whether a plain text password is equal to the salted SHA, you need to:

  1. strip the hash method-specifier with e.g. sed.
  2. decode the base64 string
  3. extract the last 4 bytes, this is the salt
  4. concatenate the the salt to the plain text password
  5. hash it
  6. compare

The base64-decoded string contains the hash in binary form and can't be printed, so we will convert it to hex with od. The first 3 steps are being done by the following code:

output=$(slappasswd -h {SSHA} -s password)
hashsalt=$( echo -n $output | sed 's/{SSHA}//' | base64 -d)
echo $output
echo $(echo -n $hashsalt | od -A n -t x1)
echo "Salt: $salt"

The output could be:


7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8 d3 62 3b 87
<------------------------- Hash --------------------------> <-- Salt-->

Salt: ▒b;▒

So now we have to concatenate the salt to the plain text password and hash it, this time without salting! The problem I had was understanding, that the salt can really be any character, including non-printable characters. In order to concatenate these non-printable characters we will use printf and their hexadecimal representations:

slappasswd -h {SHA} -s $(printf 'password\xd3\x62\x3b\x87') | sed 's/{SHA}//' | base64 -d | od -A n -t x1

The output is:

7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8

Which is equal to the hash above. Now we have verified, that 'password' matches the salted SHA.

Thanks and further reading: http://cpansearch.perl.org/src/GSHANK/Crypt-SaltedHash-0.09/lib/Crypt/SaltedHash.pm

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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