我误解了哈希盐是什么吗?

时间:2010-02-01 15:34:49

标签: hash salt

我正在努力为我们的代码库添加哈希摘要生成功能。我想使用String作为哈希盐,以便可以将预先知道的密钥/密码短语添加到需要进行哈希处理的任何内容中。我误解了这个概念吗?

5 个答案:

答案 0 :(得分:19)

salt是一个随机元素,它被添加到加密函数的输入中,目的是在每次调用时以不同的方式影响处理和输出。与“钥匙”相反,盐并不意味着保密。

一个世纪以前,加密或身份验证的加密方法是“秘密”。然后,随着计算机的出现,人们意识到保持方法完全保密很困难,因为这意味着保持软件本身的机密性。经常写入磁盘或体现为某些专用硬件的东西很难保密。因此,研究人员将“方法”分为两个不同的概念:算法(公共并成为软件和硬件)和密钥(算法的参数,存在)仅在处理期间在易失性RAM中)。密钥集中了秘密,是纯数据。当密钥存储在人类的大脑中时,它通常被称为“密码”,因为人类更善于记忆单词而不是比特。

然后钥匙本身就被分开了。事实证明,为了获得适当的加密安全性,我们需要两件事:机密参数和可变参数。基本上,为不同的用法重复使用相同的密钥往往会造成麻烦;它经常泄漏信息。在某些情况下(特别是流密码,但也有散列密码),它泄漏太多并导致成功的攻击。因此,通常需要可变性,每次加密方法运行时都会发生变化。现在好的部分是大多数时候,变化和秘密不需要合并。也就是说,我们可以将机密变量分开。所以关键是分成:

  • 密钥,通常称为“密钥”;
  • 一个变量元素,通常随机选择,根据算法类型称为“salt”或“IV”(作为“初始值”)。

只有密钥需要保密。所有相关方都需要知道变量元素,但它可以是公开的。这是一种祝福,因为共享密钥很困难;用于分发这种秘密的系统会发现容纳变量部分的成本很高,每次算法运行时都会发生变化。

在存储散列密码的上下文中,上面的解释如下:

  • “重用密钥”意味着两个用户碰巧选择了相同的密码。如果密码只是哈希,那么两个用户将获得相同的哈希值,这将显示。这是泄漏。
  • 同样,如果没有哈希,攻击者可以使用预先计算的表进行快速查找;他还可以并行攻击数千个密码。这仍然使用相同的泄漏,只是以一种证明这种泄漏是坏的原因。
  • Salting意味着向哈希函数输入添加一些可变数据。可变数据是盐。盐的意思是两个不同的用户应尽可能使用不同的盐。但是密码验证者需要能够从密码中重新计算相同的哈希值,因此他们必须能够访问盐。

由于验证者必须可以访问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)

值得一提的是,即使每个密码使用的盐应该是不同的,你的盐应该不用密码本身来计算!这种事情的实际结果是完全使你的安全无效。