题
什么是最快且安全的密码加密方法(首选 PHP)?无论您选择哪种方法,它都是可移植的?
换句话说,如果我稍后将网站迁移到其他服务器,我的密码还会继续有效吗?
正如我所说,我现在使用的方法取决于服务器上安装的库的确切版本。
解决方案
如果您正在为登录系统选择加密方法,那么速度就不是您的朋友,Jeff 与 Thomas Ptacek 就密码和密码问题进行了交流。 结论 是你应该使用你能负担得起的最慢、最安全的加密方法。
来自 Thomas Ptacek 的博客:
速度正是您在密码哈希函数中不想要的。现代密码方案受到增量密码破解者的攻击。
增量破解者不会预先计算所有可能破解的密码。他们单独考虑每个密码哈希,并通过密码哈希函数提供字典,就像 PHP 登录页面一样。像 Ophcrack 这样的彩虹表破解程序使用空格来攻击密码;John the Ripper、Crack 和 LC5 等增量破解程序会随着时间的推移而发挥作用:统计和计算。
密码攻击游戏的得分是破解密码 X 所需的时间。对于彩虹表,该时间取决于您的表需要有多大以及您搜索它的速度。对于增量破解者,时间取决于密码哈希函数运行的速度。
您对密码哈希函数的优化越好,密码哈希函数的速度就越快,您的方案就越弱。MD5 和 SHA1,甚至像 DES 这样的传统分组密码,都被设计得速度很快。MD5、SHA1 和 DES 是弱密码哈希。在现代 CPU 上,可以对 DES 和 MD5 等原始加密构建块进行位切片、矢量化和并行化,以使密码搜索速度快如闪电。游戏结束的 FPGA 实施仅需数百美元。
其他提示
我和彼得在一起。开发人员似乎不理解密码。我们都选择(我也对此感到内疚)MD5 或 SHA1,因为它们速度很快。仔细想想(因为最近有人向我指出了这一点)这没有任何意义。我们应该选择一种非常慢的哈希算法。我的意思是,从规模上来说,一个繁忙的网站会对密码进行哈希处理什么?每 1/2 分钟一次?谁在乎服务器耗时是 0.8 秒还是 0.03 秒?但这种额外的缓慢对于防止所有类型的常见暴力攻击来说是巨大的。
根据我的阅读,bcrypt 是专门为安全密码哈希而设计的。它基于blowfish,并且有很多实现。
对于 PHP,请查看 PHPPass http://www.openwall.com/phpass/
对于任何使用 .NET 的人,请查看 BCrypt.NET http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
应该指出的是,你不想 加密 密码,你想要 散列 它。
加密的密码可以被解密,让别人看到密码。散列是一种单向操作,因此用户的原始密码(以加密方式)消失了。
至于您应该选择哪种算法 - 使用当前接受的标准算法:
- SHA-256
当您对用户的密码进行哈希处理时,请务必使用它对其他一些垃圾进行哈希处理。例如。:
- 密码:
password1
- 盐:
PasswordSaltDesignedForThisQuestion
将盐附加到用户的密码中:
String s = HashStringSHA256("password1PasswordSaltDesignedForThisQuestion");
无论你做什么,都不要编写自己的加密算法。这样做几乎可以保证(除非您是密码学家)算法中存在缺陷,使得破解变得微不足道。
考虑使用 bcrypt
它被用于许多现代框架,如 Laravel。
我不一定要寻找最快的,但需要一个很好的平衡,正在开发此代码的某些服务器相当慢,散列和存储密码的脚本需要 5-6 秒才能运行,我已经将其范围缩小到散列(如果我评论散列,它会在 1-2 秒内运行)。
它不一定是最安全的,我不是为银行编码(现在),但我当然 将不会 将密码存储为纯文本。
password_hash ( string $password , int $algo [, array $options ] )
. 。(PHP 5 >= 5.5.0、PHP 7)
password_hash() 使用强大的单向哈希算法创建一个新的密码哈希。password_hash() 与 crypt() 兼容。因此,由 crypt() 创建的密码哈希可以与 password_hash() 一起使用。