【发布时间】:2011-09-22 07:03:30
【问题描述】:
我已经阅读 Stack Overflow 问题大约 15 分钟了,每一个问题似乎都与我阅读的前一个问题相矛盾。 Bcrypt、SHA1、MD5 等。我目前对我的密码进行 MD5 处理,但我想让我的数据库更安全,以防万一。
我知道这个问题已经被问了一百万次了,但我似乎在其他任何地方都找不到合适的答案。
谢谢。
【问题讨论】:
标签: php mysql encryption passwords
我已经阅读 Stack Overflow 问题大约 15 分钟了,每一个问题似乎都与我阅读的前一个问题相矛盾。 Bcrypt、SHA1、MD5 等。我目前对我的密码进行 MD5 处理,但我想让我的数据库更安全,以防万一。
我知道这个问题已经被问了一百万次了,但我似乎在其他任何地方都找不到合适的答案。
谢谢。
【问题讨论】:
标签: php mysql encryption passwords
你看到矛盾的答案是因为没有正确的答案。您应该使用您的应用程序可以支持的最安全的方法。更安全 = 更多开销。
MD5已经被破解和破解了。
根据this article,SHA1 已损坏。不过还没有破解。
bcrypt 没有(据我所知)被发现被破坏。
如果有足够的 CPU 周期,最终可以绕过任何散列或加密算法。您的决定应平衡数据的安全性和应用程序的性能。
鉴于这些警告,bcrypt 是此时的事实标准。它是为力量而不是速度而设计的,并且不知道会被破坏。有关 bcrypt 的信息索引,请参阅bcrypt article on Wikipedia。
【讨论】:
通过SALT 使用 MD5、SHA1 或任何您想要的加密。
对于这个例子,我只是为了解释而使用 MD5。
因此用户选择了一个密码,例如将其存储在 $password 中。
现在创建一个特定于您的应用程序的盐。
$salt = 'my very own salt'; // or maybe make a random string for your salt
那就做吧
$more_difficult_password = md5($salt . $password);
这样人们就不能通过谷歌搜索你的 MD5 字符串来使用字典攻击,如果它曾经以某种方式受到损害。
【讨论】:
首先,MD5 现在不是一个很好的选择。如果攻击者进入您的数据库并获得 MD5 哈希值,那么几乎可以肯定他也能够破解它们。弱密码的 MD5 哈希值甚至可以被普通计算机暴力破解。
您应该在谷歌上搜索一些关于加盐的文章,并使用该方法与更强大的哈希算法(至少 SHA1)相结合,并可能重复该过程几次。
我不打算写关于加盐的文章,因为已经写了很多关于它的文章,而且在 Stack Overflow 上你可以找到很多关于这个问题的很好的讨论。 例如。 Why do salts make dictionary attacks 'impossible'? 要么 How does password salt help against a rainbow table attack?
【讨论】:
我会选择 bcrypt。它大大降低了生成彩虹表的能力。
http://codahale.com/how-to-safely-store-a-password/
请务必注意,盐对于防止字典攻击或蛮力攻击毫无用处。您可以使用大量盐或多种盐或手工收获的、阴凉种植的有机喜马拉雅粉红盐。考虑到数据库中的哈希和盐,它不会影响攻击者尝试候选密码的速度。
【讨论】:
given the hash and the salt from your database,攻击者才能破解MD5或SHA1,甚至可能bcrypt。但是,如果他无法检测到盐是什么,我可以安全地假设我的密码(实际上是他们的加盐哈希)不会受到黑客攻击吗?
您可以通过您的密码使用您网站的密钥和每个用户的特定盐。您网站的密钥应该保存在您的数据库中,然后获取并使用。
组合变成了。
$secret = "your key from database";
$salt = "user salt";// make it randomly
$password = $_POST['password'];
$new_pass = md5($secret.$salt.$password);
现在这个组合将存储在数据库中。
登录时,再次使用此组合进行匹配。
我认为它可以帮助更多地保护您的应用程序。
干杯..!!
【讨论】:
当用户注册时,使用例如以下函数创建一个随机的salt:
$bytes = 50;
$salt = base64_encode(openssl_random_pseudo_bytes($bytes));
将其存储在数据库表中。最好的是将其存储在外部数据库中。在此之后,创建一个随机代码并将其与您的盐一起存储到外部数据库中。将随机代码存储在您的用户表中,攻击者几乎不可能找到您的盐。
在此之后,将您的密码存储在,例如:
$password_to_store_in_mysql = hash('sha512', $salt . $user_password);
当用户登录时,从外部数据库中取出盐,然后检查盐和密码是否匹配。
【讨论】: