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
{SSHA}mCXsPZkfgQYZr2mKHpy5Iav+2S2XlVU3
$ slappasswd -s secret
{SSHA}62oXsalJBuopYfHhi6hGp6AESuWNIVnd
$ slappasswd -s secret
{SSHA}0Ulc8+ugMi3NbTtWnclOFW1LKCqRdsT8
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 :)
SSHA is a salted SHA-1. By default the last 4 Bytes are the salt. The output of slappasswd is
So in order to test, whether a plain text password is equal to the salted SHA, you need to:
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:
The output could be:
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:
The output is:
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