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)感到困惑。
这是扩展的 Unix 风格的
crypt(3)
密码哈希语法,特别是它的 MD5 版本。第一个
$1$
标识哈希类型,下一部分OKgLCmVl
是用于加密密码的盐,然后在分隔$
符之后到行尾的是实际的密码哈希。因此,如果您从第一次加密中获取盐部分并将其与后续加密一起使用,您应该始终得到相同的结果:
当您更改密码时,您应该始终切换到新的盐。这可以防止任何人事后发现新密码是否与旧密码相同。(如果您想防止重复使用旧密码,您当然可以对新密码候选者进行两次哈希处理:一次使用旧盐,然后,如果结果与旧密码不同,因此可以接受,再次使用新密码盐。)
如果您不使用
openssl passwd
任何选项,您将获得原始的crypt(3)
- 兼容哈希,如 dave_thompson_085 所述。有了它,盐就是哈希的两个首字母:您不应该在任何新实现中使用这种旧的哈希样式,因为它将有效密码长度限制为 8 个字符,并且盐含量太少,无法充分防止现代方法。
(我曾经计算过为每个经典哈希存储一整套彩虹表所需的数据量
crypt(3)
。我不记得确切的结果,但假设我的计算是正确的,它大约是“一个适度的多堆栈-TB 磁盘”。在我看来,这将其置于“有组织的犯罪分子可以做到”的范围内。)与普通哈希不同,密码哈希应该使用“salt”并且应该很慢(通常通过迭代)以防止获得哈希的攻击者轻松恢复密码。请参阅security.SX 上的规范和许多与它相关的内容。
最初的1970 年代 crypt(3),为了清楚起见现在称为 DEScrypt ,是(轻微)加盐的:
稍新的 MD5crypt 方案是盐渍和迭代的,但不符合现代标准。https://en.wikipedia.org/wiki/Crypt_%28C%29详细介绍了这些以及在 Unix 上取代它们的一些更好的方案。
用户muru是对的。密码是加盐的。
您可以自己添加选项
-salt string
,哈希值保持不变。