2

所以最近我一直在做大量关于如何保护密码的研究。我相信我了解它的基本原理。因此,我正在尝试编写自己的函数来保护 php 中的密码。

但是当谈到加盐密码时,我有些困惑。我们创建一个随机唯一的 salt 并将其附加到密码,然后对其进行哈希处理,最后将未哈希处理的 salt 和哈希后的密码/salt 组合一起存储在数据库中。如果他获得对数据库和我们散列密码的访问权限,这会增加黑客的搜索空间。

所以这似乎完全是对安全性的过度杀伤,但无论我在哪里看到盐总是附加在密码的前面或后面。因此,查看单个用户的密码,这个唯一的盐不会影响搜索空间吗?尽管由于每个用户都有一个独特的盐,每个用户的整体搜索空间都大大增加了。

创建一个将盐插入密码中可预测的半随机位置(例如用户名/ 2 的长度)的算法不是更安全吗?例如,这是我提出的保护功能的步骤:

Create a random salt
take username length %(mod) password length
insert the salt at the spot determined
hash

示例运行:

random salt = 12345
len("imauserwithalongname") % len("mypass") = 2
valueToHash = my12345pass

现在我们的破解者不知道在没有看到我们的 php/source 的情况下将盐放在哪里,这(如果我错了,请纠正我)比数据库更难获得访问权限。

我也知道安全性应该取决于密钥的安全性而不是算法的保密性,但是我认为基于它添加层没有错,只要整个系统不依赖于算法的保密性。

编辑:这样做会大大增加饼干的搜索空间吗?

如果我们将盐放在一个取决于密码长度的位置,那会不会破坏使用字典攻击的目的,即使是在每个用户的基础上?

4

4 回答 4

3

将盐插入不同的位置不会增加搜索空间。如果您为每个用户使用随机盐,那么黑客无论如何都不知道每个用户的每个盐是什么。知道它在未散列字符串中的位置无关紧要。

使用bcryptPBKDF2。两种算法都强制执行盐和循环数。如果你有足够的耐心,PHP 5.5 会让你做password_hash($password).

于 2013-01-25T06:07:00.633 回答
1

因此,我正在尝试编写自己的函数来保护 php 中的密码。

哇哇,抱在那儿。

密码学家向我们这些凡人传授了一句谚语,多年来一直如此。谚语是这样的:

不要发明自己的加密货币。

大声说出来,然后再说一遍。

我知道你只是想保护你的密码,但我不得不把它弄出来。有很多很多经过尝试和测试的方法可以完成您想要实现的目标。

感谢您进行了一些研究,但互联网上充满了可怕的可怕信息,因此我将向您指出一些有用的文章。

一个不错的短名单。

这里有一些关键字可以帮助您。

  • 加密货币
  • Scrypt (当 PHP 支持它时,请有人取消它)

又是一个非常简短的清单。

解决您的具体问题。盐不需要保密,正如您所说,它们旨在阻止攻击者预先计算有效密码/哈希组合的表。但是,如果您使用弱散列算法,它们会很快失去价值。

通过默默无闻的安全性并不像看起来那么好。如果黑客获得了对您数据库的访问权,那么他们也很有可能获得对您的文件系统的访问权。如果他们可以访问您的来源,那么您存储密码的自定义方法将是一个有争议的问题。

总之,自定义算法 + 弱哈希 = 不安全。

相反,您想使用久经考验的密钥派生函数/密钥加强算法。

这些旨在使计算机非常努力地生成哈希,并使攻击者很难暴力破解密码。

Bcrypt 将盐存储在密码旁边,并且被证明是非常安全的。事实上,它足够安全,目前是安全专家推荐的散列密码的方法。

在 PHP 5.5 中,基于 Bcrypt 引入了一个简单的密码哈希 API,对于 5.5 以下的版本,有一个密码哈希兼容性库可以做同样的事情。

这对你来说应该足够了。

于 2013-01-25T08:24:34.663 回答
0

个人认为你做得太过分了。对哈希进行加盐的最有效方法是在系统上的只读文件中存储一个动态的、特定于记录的和一个静态的。这是一种非常有效但安全的加盐哈希方法。

于 2013-01-25T06:04:20.667 回答
0

我想你误解了盐的用途。盐不会增加攻击者的搜索空间,毕竟它是用哈希值存储的明文。盐的目的是,攻击者不能建立一个单一的彩虹表,然后检索所有存储的密码。

如果您将相同的盐附加到每个密码,那么攻击者不能简单地使用来自互联网的现有预先计算的彩虹表,他必须为这个盐构建一个新的彩虹表(现有的彩虹表将包含像“ horse”,但不是 horse8ze*w398dhek3+qmxno0 等密码。不幸的是,这个单一的彩虹表可以用来获取所有密码。

所以我们为每个密码使用一个唯一的盐。攻击者现在必须为每个密码构建一个单独的彩虹表,但是为什么他要继续构建该表,当他已经找到匹配项(?)时,他以后不能将该表重新用于其他密码。换句话说,蛮力比构建彩虹表要快,所以我们让彩虹表没用。

所以盐对于每个密码应该是唯一的,如果可能的话,它应该是不可预测的。确定性计算机很难满足这些标准,您能做的最好的事情就是使用操作系统的随机源来构建盐。BCrypt 和 PBKDF2 等密码的良好哈希算法会重复哈希以变慢,并在每次迭代中结合密码和原始盐。它不仅仅是密码+盐的串联。

您关于将盐放在某个秘密位置的想法确实增加了一个秘密(盐在哪里?),只要攻击者不知道您的代码,它就会起作用。获取数据库(SQL 注入)确实比获取代码更容易,但同样的目标可以用胡椒更容易地实现。

我试图在一个教程中总结这一点,也许你想看看它。

于 2013-01-25T08:16:45.473 回答