默认情况下,htpasswd 使用标准的 crypt 函数,因此密码已经加盐 - 请注意,在此示例中,两个用户的密码相同,但哈希值不同:
simon@diablo:~$ htpasswd -b -c htpasswd simon abcd
为用户 simon 添加密码
simon@diablo:~$ htpasswd -b htpasswd simon2 abcd
为用户 simon2 添加密码
simon@diablo:~$ cat htpasswd
西蒙:
NWvm/LCCxQ64E
西蒙2:
2I.LBzsRqULN6
(注意:-b 标志通常不鼓励使用,因为其他用户可以看到您的命令行参数和密码)
哈希的前两个字符是盐;通过再次调用crypt() 来验证密码。输入错误的密码会产生一个不等于散列密码的字符串:
>>> from crypt import crypt
>>> crypt("wrongpass", "NWvm/LCCxQ64E")
'NWbxQgX1unvso'
而正确的密码会产生预期的哈希:
>>> crypt("abcd", "NWvm/LCCxQ64E")
'NWvm/LCCxQ64E'
htpasswd -m 使用基于 MD5 的不同算法并使用更长的盐:
simon@diablo:~$ htpasswd -m -b -c htpasswd simon abcd
为用户 simon 添加密码
simon@diablo:~$ cat htpasswd
西蒙:
$apr1$mfvnBVmG$iIHIHOaH9vcImG5G.8eVa/
这里,盐是第二个和第三个$之间的8个字符。
htpasswd -s 存储不含盐的 SHA-1 摘要;这似乎是为了与 Netscape/LDIF 兼容:
simon@diablo:~$ htpasswd -s -b -c htpasswd simon abcd
为用户 simon 添加密码
simon@diablo:~$ htpasswd -s -b htpasswd simon2 abcd
为用户 simon2 添加密码
simon@diablo:~$ cat htpasswd
西蒙:{SHA}gf6L/odXbD7LIkJvjleEc4KRes8=
simon2:{SHA}gf6L/odXbD7LIkJvjleEc4KRes8=
这些可以很容易地反转 - 转换为十六进制摘要:
>>> "".join("%02x" % ord(c)
... for c in "gf6L/odXbD7LIkJvjleEc4KRes8=".decode("base64"))
'81fe8bfe87576c3ecb22426f8e57847382917acf'
然后使用online hash database。