在MYSQL数据库中存储密码的最佳方法

时间:2013-02-10 13:34:05

标签: php

是的我知道不建议以纯文本格式存储密码。有一种最好的方法来存储密码,以便应用程序保持安全吗?

6 个答案:

答案 0 :(得分:43)

首先,md5和sha1已被证明易受碰撞攻击,并且很容易被彩虹表示(当他们看到你的哈希在他们的普通密码数据库中是否相同时)。

目前有两件事对于您可以使用的密码足够安全。

第一个是sha512。 sha512是SHA2的子版本。 SHA2尚未被证明易受冲突攻击,sha512将生成512位哈希。这是一个例子 如何使用sha512:

<?php
hash('sha512',$password);

另一个选项叫做bcrypt。 bcrypt因其安全的哈希而闻名。它可能是最安全的,也是最可定制的。

在您想要开始使用bcrypt之前,您需要检查您的服务器是否启用了它,然后输入 这段代码:

<?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
    echo "CRYPT_BLOWFISH is enabled!";
}else {
echo "CRYPT_BLOWFISH is not available";
}

如果它返回它已启用,那么下一步很简单,只需加密密码即可(注意:为了更具可自定义性,您需要查看此How do you use bcrypt for hashing passwords in PHP?):

crypt($password, $salt);

salt通常是一个随机字符串,您在散列它们时会在所有密码的末尾添加。使用salt意味着如果有人获取了您的数据库,他们就无法检查常用密码的哈希值。使用彩虹表调用数据库。散列时应始终使用盐!

以下是我对SHA1和MD5冲突攻击漏洞的证明:
http://www.schneier.com/blog/archives/2012/10/when_will_we_se.htmlhttp://eprint.iacr.org/2010/413.pdfhttp://people.csail.mit.edu/yiqun/SHA1AttackProceedingVersion.pdf
http://conf.isi.qut.edu.au/auscert/proceedings/2006/gauravaram06collision.pdfUnderstanding sha-1 collision weakness

答案 1 :(得分:3)

哈希算法(如sha1和md5)不适合密码存储。它们的设计非常高效。这意味着暴力强迫非常快。即使黑客获得了您的哈希密码的副本,也可以非常快地强制它。如果你使用盐,它会使彩虹表的效率降低,但对蛮力无效。使用较慢的算法会使暴力无效。例如,bcrypt算法可以根据需要制作得很慢(只需更改工作因子),并在内部使用salt来防止彩虹表。如果我是你,我会采用这种方法或类似方法(例如scrypt或PBKDF2)。

答案 2 :(得分:2)

数据库中的密码应加密存储。 建议使用单向加密(散列),例如SHA2,SHA2,WHIRLPOOL,bcrypt 删除:MD5或SHA1。 (那些年纪较大,易受伤害

除此之外,您还可以使用额外的每用户生成的随机字符串 - 'salt':

$salt = MD5($this->createSalt());

$Password = SHA2($postData['Password'] . $salt);
在这种情况下,

createSalt()是一个从随机字符生成字符串的函数。

编辑: 或者如果您想要更高的安全性,您甚至可以添加2种盐: $ salt1。 $ pass。 $ salt2

您可以采取的另一项安全措施是用户停用:在5次(或任何其他数量)错误登录尝试后,用户被阻止x分钟(比如15分钟)。 它应该尽量减少暴力攻击的成功。

答案 3 :(得分:2)

为用户存储唯一的salt(例如,通过用户名+电子邮件生成),并存储密码。登录时,从数据库获取salt并使用哈希盐+密码。
使用bcrypt对密码进行哈希处理。

答案 4 :(得分:0)

最好使用crypt在DB中存储密码

示例代码:

$crypted_pass = crypt($password);

//$pass_from_login is the user entered password
//$crypted_pass is the encryption
if(crypt($pass_from_login,$crypted_pass)) == $crypted_pass)
{
   echo("hello user!")
}

文档:

http://www.php.net/manual/en/function.crypt.php

答案 5 :(得分:0)

您应该使用单向加密(这是一种加密值的方法,因此很难将其反转)。我不熟悉MySQL,但快速搜索显示它有一个password()函数,可以完成这种加密。在数据库中,您将存储加密值,当用户想要进行身份验证时,您将获取他提供的密码,使用相同的算法/函数对其进行加密,然后检查该值是否与存储在数据库中的密码相同那个用户。这假设浏览器和服务器之间的通信是安全的,即您使用https。