如何使用PHP实现双向加密的最佳方法?

7
我希望使用 PHP 中的双向加密来加密我的网站密码。我发现 mcrypt 库非常繁琐。有没有其他更简单但安全的方法?我可以使用 Zend Framework 来解决。我需要双向加密因为我的客户想要进入数据库更改或检索密码。

2
客户为什么想要检索密码?这通常是一个不好的主意。给管理员重置密码的权限,让用户在知道原始密码的情况下更改密码。 - Roger Lipscombe
4个回答

27

您应该将密码存储为哈希值(并且适当加盐)。

世界上没有任何借口可以打破这个规则。

目前,使用crypt,使用CRYPT_BLOWFISH是最佳实践。
PHP中的CRYPT_BLOWFISH是Bcrypt哈希的实现。 Bcrypt基于Blowfish块密码。

  • 如果客户端尝试登录,则对输入的密码进行哈希处理,并将其与DB中存储的哈希进行比较。 如果匹配,则授予访问权限。

  • 如果客户端想要更改密码,则需要通过一些小脚本来完成,该脚本会正确地哈希新密码并将其存储到DB中。

  • 如果客户端想要恢复密码,则应生成一个新的随机密码并发送给客户端。 新密码的哈希值存储在DB中

  • 如果客户端想要查找当前密码,则他们没有机会。 这正是哈希密码的目的:系统不知道密码,因此永远无法“查找”/窃取密码。

Jeff在博客中写道:You're Probably Storing Passwords Incorrectly

如果想使用标准库,可以查看Portable PHP password hashing framework并确保使用CRYPT_BLOWFISH算法。通常来说,直接在数据库中操作记录很容易出问题。许多人(包括非常有经验的数据库管理员)都已经深刻认识到这一点了。

我认为你想要编辑你的第一条语句,使其读作:“你应该将密码存储为哈希值”。 - Jesse Weigert
1
你是不是想在这里写 Blowfish?Blowfish 是对称密钥加密,而不是哈希。我强烈建议使用哈希而不是加密。 - thomasrutter
PHP的crypt(CRYPT_BLOWFISH标志)使用Blowfish算法实现了Bcrypt;旨在成为一种强大的哈希算法。 - Jacco
这是一个不错的“如何加密密码”的广告 - 但实际上并没有回答OP的问题。 - wbinky
为什么这是被接受的答案?它根本没有提供任何有关双向加密的信息。 - Madbreaks

8
不要加密密码。您实际上从未需要解密它们,只需要验证它们。使用mcrypt并不比什么都不做好多少,因为如果黑客侵入您的网站并窃取加密的密码,他们很可能也能够窃取用于加密它们的密钥。
为您的php应用程序创建一个单一的“密码”函数,其中您将用户的密码与盐连接,并通过sha-256哈希函数运行生成的字符串并返回结果。每当您需要验证密码时,您只需要验证密码的哈希是否与数据库中的哈希匹配。

http://phpsec.org/articles/2005/password-hashing.html


谢谢。我刚刚在我的问题中添加了这一行 - 实际上我需要双向加密,因为我的客户想要进入数据库更改密码或检索密码。 - Bamerza
2
好吧,你最好用密钥“PleaseHackMe”对密码进行异或运算。但是认真地说,说服你的客户只需要重置密码而不是检索密码。 - Jesse Weigert
这是一个很好的答案,除了我不推荐使用SHA-1算法,因为它已经被证明比预期更容易被破解。我建议使用SHA-256,或者该系列中的其他算法(如SHA-384、SHA-512等)。 - thomasrutter

4
当您真正需要以后检索密码时,至少应使用私钥和公钥,这样攻击者就需要私钥(不应存储在同一台机器上)来解密密码。
实现此目标的两个功能是 openssl_public_encrypt()openssl_private_decrypt()

这似乎是实现此目标并至少具有一定安全性的唯一方法。 - Georg Schölly
M_CRYPT是专为数据加密和解密而设计的库,OpenSSL库用于保密/安全通信。 - Jacco
这是一个足够公正的答案。我还要补充一点,您不应该在同一台服务器或任何相关服务器上存储私钥。在整个硬盘中搜索密钥相对容易。 - thomasrutter

1

要么以明文形式存储,要么存储密码的哈希值(即不可逆转)。

做任何其他操作 - 尤其是使用硬编码的对称加密 - 基本上毫无意义。

如果您按照您提出的方式进行操作,而您的计算机被攻击者入侵,攻击者将获得访问权限,不仅可以访问加密后的密码,还可以访问代码和解密它们的密钥,因此他们可能与以明文形式存储相同。

如果您希望保护数据免受他人获取物理访问计算机的影响,请使用加密文件系统(但仍需将密码以明文形式存储在其中的数据库中)。当然,在每次重新启动之前,您需要手动输入密钥才能使用系统。


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