为什么“openssl passwd”每次的输出不同?

为什么“openssl passwd”每次的输出不同?

openssl passwd 命令计算运行时输入的密码的哈希值或列表中每个密码的哈希值。密码列表从选项 -in 文件的指定文件中获取,从选项 -stdin 的标准输入中获取,否则从命令行中获取。 UNIX 标准算法 crypt 和基于 MD5 的 BSD 密码算法 1 及其 Apache 变体 apr1 均可用。

我理解“哈希”一词的意思是“将输入转换为输出,从中很难/不可能导出原始输入更具体地说,哈希后的输入:输出关系为N:M,其中M<=N(即哈希冲突是可能的)。

openssl passwd为什么使用相同的输入连续运行“ ”的输出不同?

> openssl passwd
Password:
Verifying - Password:
ZTGgaZkFnC6Pg
> openssl passwd
Password:
Verifying - Password:
wCfi4i2Bnj3FU
> openssl passwd -1 "a"
$1$OKgLCmVl$d02jECa4DXn/oXX0R.MoQ/
> openssl passwd -1 "a"
$1$JhSBpnWc$oiu2qHyr5p.ir0NrseQes1

我一定不明白这个函数的目的,因为它看起来像运行对同一输入使用相同的哈希算法会产生多个唯一的输出。我想我对这种看似 N:M 输入:输出关系感到困惑,其中 M>N。

答案1

> openssl passwd -1 "a"
$1$OKgLCmVl$d02jECa4DXn/oXX0R.MoQ/

这是扩展的 Unix 风格crypt(3)密码哈希语法,特别是它的 MD5 版本。

第一部分$1$标识哈希类型,下一部分OKgLCmVl是用于加密密码的盐,然后在分隔$符之后到行尾是实际的密码哈希。

因此,如果您从第一个加密中取出盐部分并将其与后续加密一起使用,您应该始终得到相同的结果:

> openssl passwd -1 -salt "OKgLCmVl" "a"
$1$OKgLCmVl$d02jECa4DXn/oXX0R.MoQ/
> openssl passwd -1 -salt "OKgLCmVl" "a"
$1$OKgLCmVl$d02jECa4DXn/oXX0R.MoQ/

当你在更改密码,您应该始终换用新的盐。这可以防止任何人事后发现新密码是否实际上与旧密码相同。 (如果您想防止重复使用旧密码,您当然可以对新密码候选进行哈希两次:一次使用旧密码,然后,如果结果与旧密码不同,因此可以接受,则再次使用新密码盐。)

如果不使用openssl passwd任何选项,您将获得原始的crypt(3)兼容哈希,如 dave_thompson_085 中所述。有了它,盐就是哈希值的前两个字母:

> openssl passwd "a"
imM.Fa8z1RS.k
> openssl passwd -salt "im" "a"
imM.Fa8z1RS.k

您不应在任何新实现中使用这种旧的哈希样式,因为它将有效密码长度限制为 8 个字符,并且盐太少,无法充分防范现代方法。

(我曾经计算过为每个经典哈希存储一整套彩虹表所需的数据量crypt(3)。我不记得确切的结果,但假设我的计算是正确的,它的顺序是“适度的多堆栈” -太字节磁盘”。在我看来,这将其置于“有组织的犯罪分子可以做到这一点”的范围内。)

答案2

与普通哈希不同,密码哈希值应该使用“盐”应该很慢(通常通过迭代),以防止获得哈希值的攻击者轻松恢复密码。看安全规范.SX以及许多与之相关的内容。

原来的 20 世纪 70 年代地下室(3),为了清楚起见,现在称为 DEScrypt,是(轻微)腌制:

是从集合 [a-zA-Z0-9./] 中选择的两个字符的字符串。该字符串用于以 4096 种不同方式之一扰乱算法。

稍新的 MD5crypt 方案经过加盐和迭代,但未达到现代标准。这两个方案以及一些在 Unix 上取代它们的更好方案在https://en.wikipedia.org/wiki/Crypt_%28C%29

答案3

用户穆鲁是对的。密码已加盐。

您可以自己添加选项-salt string,并且哈希值保持不变。

$ openssl passwd -salt "foo" "bar"
foXrpAKGo3142
$ openssl passwd -salt "foo" "bar"
foXrpAKGo3142

相关内容