Best way to store passwords in a mysql database?
Possible Duplicate:
How to best store user information and user login and password
How do you use bcrypt for hashing passwords in PHP?
我习惯使用md5(),我知道它现在已经过时了,我听说sha1()也不安全。那么,现在考虑到安全性,在数据库中存储和检索密码的最佳方法到底是什么呢?如果你能举个小例子,我会很高兴的。
谢谢您!
- 你看过夏2()吗?
- Bcrypt是前进的道路。
- 相关:如何安全地散列密码?
- 每当MD5出现时,一场关于MD5安全的战争就开始了。如果用足够长的细绳腌制,我还没有看到任何蛮力的成功。
- @盐不是问题所在。盐的存在可以打败彩虹表,你真的不需要一个非常大的表(64位就足够了)。问题是MD5太快了。阅读我上面发布的链接上的答案。
- 您可以直接在MySQL查询中使用aes-AES_DECRYPT(crypt_str,key_str)AES_ENCRYPT(str,key_str)…但是,密钥存储成为您的弱点。您需要解密还是可以单向散列和匹配?
- @你指的是GPU计算?有没有真正的证据证明这是可以做到的?
- @JVDBERG的GPU不是必需的,它们只会使问题变得更严重。一个标准的CPU可以每秒测试数百万(或数亿)的MD5或SHA1哈希。
- @jvdberg所有可能的哈希或加密算法都容易受到字典(彩虹表)攻击。这一切都取决于表的大小,即使找不到真正的输入,也会发现一个冲突,它将作为访问系统的令牌。除此之外…如果有人知道用户表中所有密码的散列值,那么您会遇到比散列安全性更大的问题!!!!)
- @Gungfoo-Bcrypt、Scrypt和Pbkdf2不易受到彩虹表攻击,而且从未受到过攻击。每个算法都容易受到字典和蛮力攻击,但是使用一个好的算法可以使它们更难达到几个数量级。
- 由10个字符组成的散列MD5字符串给出(128-32)^10*32字节彩虹表。即1.9e9千兆字节。隐马尔可夫模型。。需要更大的硬盘
- @jvdberg-对于1.9e9组合,2012年需要0.25秒的GPU。不需要将它们存储在硬盘上,只需尝试(蛮力)直到找到匹配项。
- @Martinstoeckli 6.6E19组合。10字节的utf-8字符串大约是1.3e30的组合。1.3E30梳子,10000e6计算/秒=4e12开裂年。
- @jvdberg-很抱歉误读了您的petabytes,是的,您可以始终使用long和save密码(带有10个字符的utf-8可能导致10-30个字节)。问题是,用户是否真的使用了如此长且难以记忆的密码?如果BCRYPT和MD5一样容易使用,为什么不使用它呢?
- 我的观点是所有关于MD5的恐怖故事都是断章取义的。一个足够长的密码+utf-8 salt将被保存很多年。
- @jvdberg-这是一个误解,salt不能计算到密码长度,它不是一个秘密,将与密码哈希一起存储。有了SQL注入攻击,您将得到这个salt。
- @Martinstoeckli如果站点容易受到SQL注入的攻击,那么散列密码有什么意义?$hash=md5(salt.$password)!
- @范德伯格-事实上这是重点!它保护用户的密码,以防攻击者使用密码散列访问数据库。这些密码通常也用于其他网站。
- php 5.5将会有一个相当好的API:gist.github.com/3707231
我建议你看看Bcrypt,因为它可以帮助你抵御暴力攻击。http://codahale.com/how-to-safety-store-a-密码/
你可以在这里找到例子
- BCRYPT是唯一一种专门设计的不易破裂的方法。sha1、sha256,尤其是md5不够。
- Bcrypt不是唯一的方法。还有scrypt(使用更多的内存——这是一件好事)和pbkdf2(类似于bcrypt,但不是很好)。
您真的应该使用bcrypt来散列密码,它是专门为散列密码而设计的。
密码的哈希函数应该很慢(需要一些计算时间)。大多数散列算法(如sha-1和md5,甚至sha-256)都设计得很快,但这使得它很容易成为暴力攻击的目标。一个现成的GPU能够计算大约每秒8千兆MD5哈希!
不要害怕使用bcrypt!它不仅适用于高安全性的站点,而且使用它和使用MD5哈希一样容易。建议使用像phpass这样的成熟库,如果您想了解如何实现它,可以阅读本文,在这里我试图解释最重要的几点。
更新:
当前的PHP版本提供了password_hash()和password_verify()函数来处理密码。像这样使用它们:
1 2 3 4 5 6 7
| // Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb); |
- 以防万一有人想知道——bcrypt在一般意义上并不慢(如果你想的话,你可以让它能够每秒哈希数百或数千个密码)。重要的是,它的速度不如MD5或SHA1(每秒可以散列数亿个密码)。普通人不需要每秒散列数亿个密码,但攻击者需要。
- @布兰登-朗-是的,区别在于,它提供了一个成本因素,它决定了哈希的迭代次数。将成本系数增加1,使所需时间加倍,使算法适用于未来(因此速度更快)的硬件。
我们将crypt与河豚一起使用:
1 2 3 4 5 6 7
| // Hash our password
$hashed = crypt($plain_text_password, '$2a$08$' . substr(hash('whirlpool', microtime()), rand(0, 105), 22));
// Validate a password
if (crypt($plain_text_password, $hashed) == $hashed)) {
// Valid password
} |
盐前缀$2a$(阅读文档)指示crypt使用河豚。假设底层操作系统中的crypt(3)的实现支持它,您就可以"免费"得到它。
- 我真的不明白这部分在做什么:. substr(hash('whirlpool', microtime()), rand(0, 105), 22)。
- 它使用whirlpool算法根据当前时间生成128个字符的散列值,然后从散列值中提取22个字符,并将它们附加到传递给crypt的salt中。
- 显然,调用rand()的次数越多,应用程序就越安全。露齿而笑
- 如果你想要的只是一个盐,那么仅仅获取22个字符的随机数据就更简单(更快)。
MD5sha1+唯一盐=最佳方式
别妄想。
- MD5sha1+uniqe盐比你自己的自行车最好
- 不,不是。太快了,太复杂了。使用BCRIPT。
- 他问的是md5-sha1,而不是其他的func。我在Rails应用程序中使用bcrypt,在php中使用md5-sha1。
- 语言的选择与之无关。MD5和SHA1不是为密码散列而设计的(更具体地说,它们不是密钥派生函数)。为什么在存在安全函数时使用不安全函数?
您可以查找大量加密代码或将它们混合,例如:
我觉得那是不必要的,所以我用的是sha512 hash("sha512",$pw);。
- 不。请不要像这样发表误导性的回答。
- 这不一定是个坏主意,但在做之前你应该先理解它的含义。您不会通过链接哈希函数自动获得更好的安全性。