什么是SALT?我该如何使用它?

45

我一直在寻找,但仍不确定“salt”是什么以及如何使用/实现它。抱歉问这个问题可能有点幼稚,因为我是自学php的。


14
http://en.wikipedia.org/wiki/Salt_(cryptography) - ceejayoz
1
http://www.php.net/manual/en/faq.passwords.php - Yasen
1
https://en.wikipedia.org/wiki/Salt 和薯条很搭! - DreamTeK
7个回答

47
我绝对不是专家,但简短的答案是,“加盐”一行文本意味着在其末尾添加几个额外的字符。您可以使用“abcdefg”来为“salt”加盐,以获得“saltabcdefg”。如果“salt”恰好是您想要使人难以猜测的密码,则这可能很有用。
通常,密码+盐通过某些难以逆转的过程进行转换(“哈希”)成完全不同的字符串。然后将此转换后的字符串作为密码存储,连同盐的纯文本和原始密码的纯文本一起丢弃。当您想要检查某人是否输入了正确的密码时,您将其输入内容与密码文件中列出的盐相结合,然后对结果进行哈希。如果结果与您记录的密码哈希匹配,则知道他们输入了正确的密码。
实施盐可以像选择一个字符串作为盐一样容易,并确保跟踪它。但是,您可以针对每个密码变化盐,然后必须有一种方法来跟踪密码+盐组合以及生成变化。当然,您可能还想对密码进行哈希而不是保存密码的纯文本,因此您必须选择哈希函数。此时,问题已从加盐正确转向实施密码安全方案。
对于PHP,您可能希望查看一些框架如何实现此操作。两个快速链接分别是CakePHP和Zend。

http://www.jotlab.com/2010/04/18/cakephp-rainbow-table-protection-behaviour/

http://www.zimuel.it/blog/2009/07/build-a-secure-login-with-zend-framework/


另外,如果盐值存储在数据库中(每个用户不同),我猜它需要与密码一起进行哈希处理。那么从数据库中获取哈希盐的最佳方法是什么,以便将其与存储的密码进行比较测试?谢谢。 - Drewdin
我的印象是盐以明文形式存储。将盐与密码一起进行哈希处理将有效地要求用户键入密码+盐。但是,将盐以明文形式存储并不是很糟糕,因为它的主要目的是使攻击者更难攻击具有大量预计算“此哈希等于此密码”值(即彩虹表)的密码文件。换句话说,攻击者可以尝试根据盐修改他们的方法,但他们仍然必须从头开始重新计算事物。 - Approximately Linear
CakePHP文章在WebArchive上的链接(https://web.archive.org/web/20170308143021/http://www.jotlab.com:80/2010/cakephp-rainbow-table-protection-behaviour), Zend似乎已经彻底消失了 =( - user8554766
PHP的password_hash()函数会自动添加盐... https://www.geeksforgeeks.org/how-to-secure-hash-and-salt-for-php-passwords/ - Elijah Mock

28

当我第一次提出这个问题时,许多年前,有人回答说,“盐对食物有什么作用?”答案是它为食物增添了变化。 密码学“盐”的背后理念是,在字符串的开头或结尾添加某些内容,以便两个相同的密码不会哈希到相同的加密值。

考虑这个例子- 如果我的密码非常常见,比如"hello123",然后它与所有其他"hello123"密码具有完全相同的加密哈希值,那么我难道不能在散列密码列表中查看谁还有相同的加密哈希值,并使用我的密码登录他们的账户吗?


2
谢谢,SALT会改变还是保持不变? - Drewdin
我问的原因是,同样的密码和盐值不会以相同的方式进行哈希吗?我将阅读提供的链接。谢谢。 - Drewdin
5
使用相同的盐值和密码进行哈希处理会得到相同的结果,是的。一些人会对每个用户使用不同的盐值以增加安全性。即使使用一个共享的盐值也会显著提高安全性——某人拥有预生成的使用您特定盐值的哈希列表的机会很小。 - ceejayoz

7

盐是添加到您想要加密或哈希的字符串中的(短)字符串。例如:

<?php
 $password = 'abcdefg';
 $salt = 'anythingyouwant_';
 $pw_hash = md5($salt.$password);
?>

这样做可以增加哈希的安全性,因为“anythingyouwant_abcdefg”在哈希数据库中很可能没有存储(http://en.wikipedia.org/wiki/Rainbow_tables)。


但是仍然可以轻易地猜出“abcdefg”,因此,没有盐也无济于事。 - Your Common Sense
当然可以猜测。如果哈希值被暴露(例如,如果我使用用户登录凭据访问您的数据库),那么盐只有帮助作用。如果我知道“abcdefg”的哈希值(这并不难猜测),我可以在您的数据库中开始寻找此哈希值。但是,由于我不知道您添加的盐,因此我将无法找到相应的密码。 - stlvc
1
有些常用的密码,像“applejuice”,“abcdefg”,“ball”等,很容易被用户使用。你可以为自己对这些密码进行哈希处理,这样就能得到这些密码的哈希值。而盐,则是由你自己添加到这些密码中的,只有你知道盐的具体内容。 - stlvc
问问自己盐如何被暴露。 - stlvc
是的,这就是为什么即使使用加盐技术,您的密码也应该很强壮。 - Your Common Sense
显示剩余10条评论

6

不知道为什么这个回答被踩了,它是一个完全有效的答案。 - GordonM
我给你点赞,只是因为你应该得到一票,感谢Gordon :) - Cogicero

0

0

让我们将几个哈希算法结合起来,制作一个双重哈希算法,使事情有些变化:

$password = "myPassword";
$salt = sha1(md5($password)).'k32duem01vZsQ2lB8g0s'; 
$password = md5($password.$salt);

正如您所看到的,我们首先使用双重哈希算法(md5和sha1)对密码进行哈希,并与创建的盐值键连接。之后,我们将真实密码与生成的盐值组合在一起,并再次使用md5进行哈希。优点是这种方式的盐值是随机的并且会变化,使其几乎不可能被破解。我的意思是,如果您可以等待一百万年并拥有一台超级计算机,那么可以尝试去破解它。


1
很抱歉要这么说,但你在这里几乎做错了所有事情。MD5/SHA1太快了,应该使用像BCrypt或PBKDF2这样的慢哈希函数。如果盐是从密码本身派生的,则完全失去了其优势,在其中没有任何更多的随机性。使用此算法散列的示例密码将在几秒钟内被破解,使用一个体面的破解工具。如果您有兴趣,请查看我的有关安全存储密码的教程 - martinstoeckli
教程非常清晰,感谢您的清晰解释。如果我们添加自己的密钥串联,则破解可能性将减小到一定程度,我希望如此。- @martinstoeckli - Mahendra Jella
如果您以这种方式添加密钥,则会添加一种辣椒,这是一种改进,因为攻击者现在需要在服务器上拥有特权。虽然这并不使盐更安全,但如果仍然不是随机的,并且攻击者知道辣椒,则仍然从密码派生。此外,有一种更好的方法可以添加服务器端秘密,请查看有关加密哈希的教程的最后部分。 - martinstoeckli

0
盐和哈希是一种在数据库中存储密码的技术。在密码学中,盐是指在密码之后添加一些内容,然后进行哈希处理。因此,盐和哈希提供了两个安全级别。盐始终生成唯一的密码,即如果存在两个相同的密码,在添加盐后,生成的字符串将会改变。盐与哈希结合使用可以增加密码的安全级别。
语法:
string password_hash( string $pass, int $algo, array $options )
参数:
1. $pass:这个参数保存了要保护并存储在数据库中的密码。 2. $algo:它指定了用于创建$pass哈希的哈希算法。 3. $options:这是盐的部分。它以成本因素的形式接受盐。它是可选的,如果留空,则默认成本将添加到字符串中(在大多数情况下为10)。请注意,更高的成本会导致更强的密码保护,从而给CPU带来更大的负载。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接