目前称MD5部分不安全。考虑到这一点,我想知道使用哪种机制来保护密码
这个问题,“双重散列”是不是比只对密码进行一次散列更不安全?
建议多次散列可能是一个好主意,但是如何为单个文件实现密码保护?建议使用盐
我正在使用PHP。我想要一个安全快速的密码加密系统。对密码进行一百万次哈希运算可能更安全,但速度也较慢。如何在速度和安全之间取得良好的平衡?另外,我更希望结果具有恒定数量的字符
- 散列机制必须在PHP中可用
- 它必须是安全的
- 它可以使用盐(在这种情况下,所有的盐都一样好吗?有没有办法产生好的盐?)
另外,我是否应该在数据库中存储两个字段(例如,一个使用MD5,另一个使用SHA)?它会让它更安全还是不卖
如果我不够清楚,我想知道应该使用哪个散列函数,以及如何选择一个好的salt,以便有一个安全、快速的密码保护机制
没有完全涵盖我问题的相关问题:
PHP中SHA和MD5的区别是什么
简单密码加密
存储asp.net密钥和密码的安全方法
如何在Tomcat5.5中实现salt密码
免责声明:这个答案写在2008年
此后,PHP为我们提供了
password\u hash和password\u verify,并且自其推出以来,它们是推荐的密码哈希&;检查方法尽管如此,答案的理论仍然是一本很好的读物
TL;博士
不要
- 不要限制用户可以输入的密码字符。只有傻瓜才会这么做
- 不要限制密码的长度。如果你的用户想要一个包含SuperCalifragilisticExpialidious的句子,不要阻止他们使用它
- 不要删除或转义密码中的HTML和特殊字符
- 切勿以纯文本形式存储用户密码
- 切勿通过电子邮件向用户发送密码,除非他们丢失了密码,并且您发送了临时密码
- 永远不要以任何方式记录密码
- 永远不要用SHA1或MD5甚至SHA256散列密码!现代的破解速度可以分别超过600亿和1800亿哈希/秒
- 不要将bcrypt和与hash()的原始输出混用,使用十六进制输出或base64_编码。(这适用于任何可能含有流氓
\0的输入,这会严重削弱安全性。)
Dos
- 尽可能使用scrypt;B如果你不能,请回答
- 如果不能使用bcrypt或scrypt,请使用PBKDF2和SHA2哈希
- 数据库受损时重置每个人的密码
- 实现合理的8-10个字符的最小长度,并且至少需要1个大写字母、1个小写字母、一个数字和一个符号。这将提高密码的熵,从而使密码更难破解。(有关一些讨论,请参阅“什么是好密码?”部分。)
为什么还要散列密码
哈希密码背后的目标很简单:通过破坏数据库防止恶意访问用户帐户。因此,密码散列的目标是通过花费大量时间或金钱来计算纯文本密码来阻止黑客或破解者。时间/成本是你的武器库中最好的威慑因素
您希望对用户帐户进行良好、健壮的哈希的另一个原因是给您足够的时间更改系统中的所有密码。如果您的数据库遭到破坏,您至少需要足够的时间来锁定系统,如果不更改数据库中的每个密码
Whitehat Security首席技术官Jeremiah Grossman在White Hat Security博客上表示,最近的密码恢复需要暴力破解他的密码保护:
有趣的是,在经历了这场噩梦之后,我学到了很多我不知道的关于密码破解、存储和复杂性的知识我开始明白为什么密码存储比密码复杂性更重要。如果您不知道密码是如何存储的,那么您真正可以依赖的就是复杂性。这可能是密码和加密专业人士的常识,但对于一般的信息安全或网络安全专家来说,我非常怀疑
(我的重点。)
是什么让密码变得好呢
熵。(我并不完全同意Randall的观点。)
简言之,熵是密码内的变化量。当密码只有小写罗马字母时,只有26个字符。这并不是很大的变化。字母数字密码更好,有36个字符。但允许大写和小写,加上符号,大约是96个字符。这比只写字母要好得多。一个问题是,为了让我们的密码令人难忘,我们插入了减少熵的模式。哎呀
密码熵易于逼近。使用全部ascii字符(大约96个可键入字符)会产生每个字符6.6的熵,对于未来的安全性来说,8个字符的密码仍然太低(52.679位熵)。但好消息是:更长的密码和带有unicode字符的密码确实增加了密码的熵,使其更难破解
在Crypto StackExchange站点上有一个关于密码熵的较长讨论。一个好的谷歌搜索也会得到很多结果
在我与@Popleak交谈的评论中,他指出,强制执行一个X长度、X个字母、数字、符号等的密码策略,实际上可以通过使密码方案更可预测来降低熵。我同意。随机性,尽可能真实的随机性,总是最安全但最不值得记忆的解决方案
就我所知,制作世界上最好的密码是一件难事。要么是不值得记忆,要么是太容易预测,要么是太短,要么是太多的unicode字符(在Windows/Mobile设备上很难键入),要么是太长,等等。没有任何密码能够真正满足我们的需要,所以我们必须像在诺克斯堡一样保护它们
最佳做法
Bcrypt和scrypt是当前的最佳实践。Scrypt在时间上会比bcrypt好,但它还没有被Linux/Unix或web服务器视为标准,也没有发布对其算法的深入审查。但尽管如此,该算法的未来看起来还是很有希望的。如果您正在使用Ruby,那么有一个scrypt gem可以帮助您,Node.js现在有了自己的scrypt包。您可以通过Scrypt扩展或libnaude扩展在PHP中使用Scrypt(两者都可以在PECL中使用)
如果您想了解如何使用bcrypt,或者为自己找到一个好的包装器,或者使用类似PHPASS的东西来实现更传统的实现,我强烈建议您阅读crypt函数的文档。我建议至少12轮bcrypt,如果不是15到18轮的话
当我得知bcrypt只使用河豚的关键进度表,并采用可变成本机制时,我改变了使用bcrypt的想法。后者通过增加blowfish已经很昂贵的密钥计划,增加了暴力破解密码的成本
一般做法
我几乎无法再想象这种情况了。PHPASS支持php3.0.18到5.3,因此它在几乎所有可以想象的安装上都是可用的,如果您不知道您的环境支持bcrypt,那么应该使用它
但假设您根本不能使用bcrypt或PHPASS。然后呢
尝试使用您的环境/应用程序/用户感知所能容忍的最大轮数实现PDKBF2。我建议的最低数量是2500发。此外,如果可以使用hash_hmac()使操作更难重现,请确保使用它
今后的做法
PHP5.5提供了一个完整的密码保护库,它可以消除使用bcrypt时的任何痛苦。虽然我们大多数人在大多数常见环境中,尤其是共享主机中,都坚持使用PHP5.2和5.3,但@ircmaxell为即将推出的API构建了一个向后兼容PHP5.3.7的兼容层
密码学概述&;免责声明
实际上破解散列密码所需的计算能力并不存在。计算机“破解”密码的唯一方法是重新创建密码并模拟用于保护密码的哈希算法。散列的速度与其被强制执行的能力成线性关系。更糟糕的是,大多数散列算法可以很容易地并行化,从而执行得更快。这就是为什么像bcrypt和scrypt这样昂贵的计划如此重要的原因
您不可能预见到所有威胁或攻击途径,因此必须尽最大努力提前保护您的用户。如果你不这样做,那么你甚至可能错过你被攻击的事实,直到为时已晚<你有责任。为了避免这种情况,首先要表现得多疑。攻击您自己的软件(内部)并尝试窃取用户凭据,或修改其他用户的帐户或访问其数据。如果您不测试系统的安全性,那么除了您自己,您不能责怪任何人
最后:我不是一个密码学家。我所说的都是我的观点,但我碰巧认为这是基于良好的常识。。。还有大量的阅读。请记住,要尽可能地偏执,使事情尽可能不被侵入,然后,如果您仍然担心,请联系白帽黑客或密码专家,看看他们对您的代码/系统有何评论