所以最近我一直在做大量关于如何保护密码的研究。我相信我了解它的基本知识。因此,我正在尝试编写自己的函数来保护 php 中的密码。
但是在加盐密码时,我有些困惑。我们创建一个随机的唯一盐并将其附加到密码中,然后对其进行哈希处理,最后将未散列的盐和散列的密码/盐组合一起存储在数据库中。如果黑客获得对数据库和我们的哈希密码的访问权限,这将增加黑客的搜索空间。
所以这似乎是完全的过度安全,但是我看到的任何地方都总是将盐附加到密码的正面或背面。因此,查看单个用户的密码,这种独特的盐不会影响搜索空间,不是吗?尽管由于每个用户都有独特的盐,因此每个用户的整体搜索空间都大大增加。
创建一种算法,将盐插入密码中可预测的半随机位置(例如用户名/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,这(如果我错了,请纠正我)比数据库更难访问。
我也知道安全性应该取决于密钥的安全性而不是算法的保密性,但是我认为基于它添加层没有错,只要整个系统不依赖于算法的保密性。
编辑:这样做会大大增加饼干的搜索空间吗?
如果我们把盐放在一个取决于密码长度的地方,那不会破坏使用字典攻击的目的,即使是在每个用户的基础上吗?
盐插入不同的位置不会增加搜索空间。 如果您为每个用户使用随机盐,黑客无论如何都不知道每个用户的每种盐是什么。 知道它在未散列字符串中的位置并不重要。
使用 bcrypt
或 PBKDF2
。 这两种算法都强制执行盐和循环数。 如果你有足够的耐心,PHP 5.5 会让你做password_hash($password)
。
因此,我正在尝试编写自己的函数来保护密码 在 PHP 中。
哇哇哇,拿着它。
有一句话从密码学家那里流传下来,传给我们凡人,这句话已经存在了很多年。俗话是这样的:
不要发明自己的加密货币。
大声说出来,然后再说一遍。
我知道你只是想保护你的密码,但我必须把它排除在外。有很多很多久经考验的方法可以完成您想要实现的目标。
我很欣赏你做了一些研究,但互联网上充满了可怕的可怕信息,所以我将向你指出一些有用的文章。
- 查看 ircmaxell 的安全相关博客。
一个不错的简短清单。
这里有一些关键字可以帮助您。
- 地穴
Scrypt(当PHP支持它时,有人请取消删除它)
又是一个非常简短的清单。
解决您的具体问题。盐不需要保密,正如您所说,它们旨在阻止攻击者预先计算有效密码/哈希组合的表。但是,如果您使用弱哈希算法,它们很快就会失去其值。
通过默默无闻获得安全并不像看起来那么好。如果黑客获得了对您的数据库的访问权限,那么他们也很有可能访问您的文件系统。如果他们可以访问您的源代码,那么您存储密码的自定义方法是一个有争议的问题。
综上所述,自定义算法 + 弱哈希 = 不安全。
相反,您希望使用久经考验的密钥派生函数/密钥强化算法。
这些旨在使计算机非常努力地生成哈希,并使攻击者很难暴力破解密码。
Bcrypt将盐存储在密码旁边,并被证明是非常安全的。事实上,它足够安全,目前是安全专家推荐的散列密码方法。
在 PHP 5.5中引入了基于 Bcrypt 的简单密码哈希 API,对于 5.5 以下的版本,有一个密码哈希兼容性库可以执行完全相同的操作。
这对你来说应该足够了。
我个人认为你做得太过分了。加盐哈希的最有效方法是将动态的、记录指定的哈希和静态的存储在系统上的只读文件中。这是一种非常有效但安全的加盐哈希方法。
我想你误解了盐的目的。盐不会增加攻击者的搜索空间,毕竟它是与哈希值一起存储的明文。盐的目的是,攻击者无法构建一个彩虹表,然后检索所有存储的密码。
如果你将相同的盐附加到每个密码,那么攻击者不能简单地使用互联网上现有的预先计算的彩虹表,他必须为这个盐构建一个新的彩虹表(现有的彩虹表将包含像"horse"这样的密码,但不包含像horse8ze*w398dhek3+qmxno0这样的密码)。不幸的是,这个彩虹表可以用来获取所有密码。
因此,我们为每个密码使用唯一的盐。攻击者现在必须为每个密码构建一个单独的彩虹表,但是当他已经找到匹配项(?)时,他为什么要继续构建该表,他以后无法将该表重用于其他密码。换句话说,蛮力比建造彩虹表更快,所以我们让彩虹表变得无用。
因此,每个密码的盐应该是唯一的,如果可能的话,它应该是不可预测的。这些标准很难用确定性计算机来满足,你能做的最好的事情就是使用操作系统的随机源来构建盐。像BCrypt和PBKDF2这样的密码的良好哈希算法重复哈希变得缓慢,并在每次迭代中结合密码和原始盐。它不仅仅是密码+盐的串联。
你关于把盐放在秘密的地方的想法确实增加了一个秘密(盐在哪里?),只要攻击者不知道你的代码,它就会起作用。获取数据库(SQL注入)确实比访问代码更容易,但是使用辣椒可以实现相同的目标。
我试图在教程中总结这一点,也许你想看看它。