Выход Slappasswd рандомизированный

10

Я ожидал slappasswdполучить фиксированный хеш, но похоже, что выходные данные рандомизированы, так как я никогда не получаю одинаковые выходные данные для одного и того же входного пароля:

$ slappasswd -s secret
{SSHA}mCXsPZkfgQYZr2mKHpy5Iav+2S2XlVU3
$ slappasswd -s secret
{SSHA}62oXsalJBuopYfHhi6hGp6AESuWNIVnd
$ slappasswd -s secret
{SSHA}0Ulc8+ugMi3NbTtWnclOFW1LKCqRdsT8

Как во время аутентификации slapd знает, как таким же образом рандомизировать хеш для предоставленного пароля, чтобы он мог соответствовать паролю, определенному в первую очередь?

Максимум
источник

Ответы:

8

Выступая здесь, но я предполагаю, что slappasswd использует соленый хеш вместо простого хеша. Это означает, что он добавляет случайный префикс к вашему паролю и сохраняет этот случайный префикс как часть строки, которую вы видите в выходных данных slappasswd. Когда вы вводите свой пароль, он добавляет к нему префикс, хэширует результат и сравнивает его со строкой в ​​выводе slappasswd. Если он совпадает, вы находитесь. Если это не так, ваш пароль был неправильным :)

wzzrd
источник
3
Верно. В частности, для хеш-метода по умолчанию используется slappasswd{SSHA} или соленая версия SHA-1.
Джастароберт
Я согласен, но мой вопрос остается: если соль окажется частью хэша, это означает, что вы не можете извлечь соль из хешированного пароля. Соответственно, как slapd знает, какую соль добавлять при проверке пароля? (он должен добавить ту же соль, чтобы хешированные пароли были одинаковыми).
Макс
3
@user: Часть после {SSHA}содержит и соль, и хэш.
user1686
8

SSHA - это соленая SHA-1. По умолчанию последние 4 байта являются солью. Выходные данные slappasswd

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

Таким образом, чтобы проверить, равен ли простой текстовый пароль соленому SHA, вам необходимо:

  1. удалите спецификатор метода хеша с помощью, например, sed.
  2. декодировать строку base64
  3. извлечь последние 4 байта, это соль
  4. конкатенировать соль в простой текстовый пароль
  5. хэш это
  6. сравнить

Декодированная base64 строка содержит хеш в двоичном виде и не может быть напечатана, поэтому мы преобразуем ее в шестнадцатеричный формат с помощью od. Первые 3 шага выполняются с помощью следующего кода:

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

Выход может быть:

{SSHA}fDu0PgKDn1Di9W1HMINpPXRqQ9jTYjuH

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;▒

Так что теперь мы должны объединить соль с простым текстом и хешировать его, на этот раз без соли! У меня была проблема с пониманием, что солью может быть любой символ, включая непечатные символы. Чтобы объединить эти непечатаемые символы, мы будем использовать printf и их шестнадцатеричные представления:

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

Выход:

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

Который равен хешу выше. Теперь мы убедились, что «пароль» соответствует соленому SHA.

Спасибо и дальнейшего чтения: http://cpansearch.perl.org/src/GSHANK/Crypt-SaltedHash-0.09/lib/Crypt/SaltedHash.pm

mxmlnkn
источник