Slappasswd 输出随机化

Max*_*Max 10 openldap

我希望slappasswd产生一个固定的哈希值,但似乎输出是随机的,因为对于相同的输入密码,我从来没有得到相同的输出:

$ slappasswd -s secret
{SSHA}mCXsPZkfgQYZr2mKHpy5Iav+2S2XlVU3
$ slappasswd -s secret
{SSHA}62oXsalJBuopYfHhi6hGp6AESuWNIVnd
$ slappasswd -s secret
{SSHA}0Ulc8+ugMi3NbTtWnclOFW1LKCqRdsT8
Run Code Online (Sandbox Code Playgroud)

在身份验证期间,slapd如何知道如何以相同的方式随机化提供的密码的哈希值,以便它可以匹配最初定义的密码?

wzz*_*zrd 8

在这里冒险,但我认为 slappasswd 使用的是加盐哈希而不是普通哈希。这意味着它会为您的密码添加一个随机前缀,并将该随机前缀保存为您在 slappasswd 输出中看到的字符串的一部分。当您输入密码时,它会为其添加前缀,对结果进行散列并将其与 slappasswd 输出中的字符串进行比较。如果匹配,您就在。如果不匹配,则您的密码错误:)

  • 的确。特别是,`slappasswd` 的默认哈希方法是 {SSHA},或 SHA-1 的加盐版本。 (3认同)
  • @user:`{SSHA}` 之后的部分包含 _both_ 盐和哈希。 (3认同)

mxm*_*nkn 8

SSHA 是一种加盐的 SHA-1。默认情况下,最后 4 个字节是盐。slappasswd 的输出是

'{<Hash Method>}<base64 converted hash and salt>'
Run Code Online (Sandbox Code Playgroud)

所以为了测试一个纯文本密码是否等于salted 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"
Run Code Online (Sandbox Code Playgroud)

输出可能是:

{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;?
Run Code Online (Sandbox Code Playgroud)

所以现在我们必须将 salt 连接到纯文本密码并对其进行哈希处理,这次没有加盐!我遇到的问题是理解盐实际上可以是任何字符,包括不可打印的字符。为了连接这些不可打印的字符,我们将使用 printf 及其十六进制表示:

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

输出是:

7c 3b b4 3e 02 83 9f 50 e2 f5 6d 47 30 83 69 3d 74 6a 43 d8
Run Code Online (Sandbox Code Playgroud)

这等于上面的哈希值。现在我们已经验证,“密码”与加盐的 SHA 匹配。

感谢并进一步阅读:http : //cpansearch.perl.org/src/GSHANK/Crypt-SaltedHash-0.09/lib/Crypt/SaltedHash.pm