我正在努力为我们的代码库添加哈希摘要生成功能。我想使用String作为哈希盐,以便可以将预先知道的密钥/密码短语添加到需要进行哈希处理的任何内容中。我误解了这个概念吗?
答案 0 :(得分:19)
salt是一个随机元素,它被添加到加密函数的输入中,目的是在每次调用时以不同的方式影响处理和输出。与“钥匙”相反,盐并不意味着保密。
一个世纪以前,加密或身份验证的加密方法是“秘密”。然后,随着计算机的出现,人们意识到保持方法完全保密很困难,因为这意味着保持软件本身的机密性。经常写入磁盘或体现为某些专用硬件的东西很难保密。因此,研究人员将“方法”分为两个不同的概念:算法(公共并成为软件和硬件)和密钥(算法的参数,存在)仅在处理期间在易失性RAM中)。密钥集中了秘密,是纯数据。当密钥存储在人类的大脑中时,它通常被称为“密码”,因为人类更善于记忆单词而不是比特。
然后钥匙本身就被分开了。事实证明,为了获得适当的加密安全性,我们需要两件事:机密参数和可变参数。基本上,为不同的用法重复使用相同的密钥往往会造成麻烦;它经常泄漏信息。在某些情况下(特别是流密码,但也有散列密码),它泄漏太多并导致成功的攻击。因此,通常需要可变性,每次加密方法运行时都会发生变化。现在好的部分是大多数时候,变化和秘密不需要合并。也就是说,我们可以将机密与变量分开。所以关键是分成:
只有密钥需要保密。所有相关方都需要知道变量元素,但它可以是公开的。这是一种祝福,因为共享密钥很困难;用于分发这种秘密的系统会发现容纳变量部分的成本很高,每次算法运行时都会发生变化。
在存储散列密码的上下文中,上面的解释如下:
由于验证者必须可以访问salt,但不需要保密,因此通常会将salt值与散列值一起存储。例如,在Linux系统上,我可以使用此命令:
openssl passwd -1 -salt "zap" "blah"
这计算哈希密码,哈希函数MD5适合在/etc/password
或/etc/shadow
文件中使用,用于密码"blah"
和盐"zap"
(在这里,我明确选择了盐,但在实际条件下应该随机选择)。然后输出:
$1$zap$t3KZajBWMA7dVxwut6y921
其中美元符号作为分隔符。初始"1"
标识散列方法(MD5)。盐在那里,用明文表示。最后一部分是哈希函数输出。
关于如何将salt和密码作为输入发送到散列函数的规范(某处)(至少在glibc源代码中,可能在其他地方)。
“登录和密码”用户身份验证系统中的编辑,“登录”可以作为可通行的盐(两个不同的用户将具有不同的登录)但这不会捕获给定用户更改密码的情况(新密码是否与旧密码相同会泄漏)。
答案 1 :(得分:3)
您完全理解这个概念。只要确保每次都能重复使用前置盐。
答案 2 :(得分:2)
如果我理解正确,听起来你说得对。该过程的伪代码类似于:
string saltedValue = plainTextValue + saltString;
// or string saltedalue = saltString + plainTextValue;
Hash(saltedValue);
Salt只会为试图获取信息的人增加另一层复杂程度。
答案 3 :(得分:0)
如果每个加密短语的盐不同,那就更好了,因为每个盐都需要自己的彩虹表。
答案 4 :(得分:0)
值得一提的是,即使每个密码使用的盐应该是不同的,你的盐应该不用密码本身来计算!这种事情的实际结果是完全使你的安全无效。