我应该使用generate_password_hash()将所有加密密码存储到数据库

时间:2016-09-03 08:00:10

标签: python encryption flask

当我使用generate_password_hash()函数时,我得到一个包含随机盐的加密密码字符串。

>>> from werkzeug.security import generate_password_hash, check_password_hash
>>> generate_password_hash('password')
>>> 'pbkdf2:sha1:1000$3j8Brovx$9acddcd67da9e4c913817231c882a0f757e2d095'

如果我将此字符串存储到数据库,其他人入侵我的数据库并获取此字符串,则使用强力破解可以轻松获取原始密码,因为加密密码包含盐。

check_password_hash('pbkdf2:sha1:1000$9HycZ0Qa$94f08a91fba1c040c5bffb6c7e1ab5a6ad4818de', 'password')

在使用generate_password_hash()之前,我是否应首先使用自己的盐加密原始密码,还是有更好的解决方案?

感谢。

2 个答案:

答案 0 :(得分:2)

  

使用暴力破解很容易获得原始密码,因为加密密码包含盐。

不,它很容易"蛮力,因为你的迭代次数很少为1000。

  

在使用generate_password_hash()之前,我是否应首先使用自己的盐加密原始密码,还是有更好的解决方案?

不,加密是可逆的,因为丢失的数据库也意味着加密密钥也可能丢失,这意味着额外的加密是无用的。

一个简单的解决方法是将迭代次数增加到一百万或一千万,具体取决于您的服务器上可以承受的费用,因为身份验证程序较慢,您的用户不会逃跑。

generate_password_hash('password', method='pbkdf2:sha256:1000000')

PBKDF2的问题在于它可以很容易地并行化,因为它不需要太多内存。有一些替代品,如scrypt和Argon2,可配置为需要大量内存。内存是目前基于ASIC的专用密码暴力破解机的主要限制。

最终,如果您的用户正在使用"密码1"那么,您所做的任何事情都将导致安全的身份验证系统。作为他们的密码。您应该要求您的用户使用至少包含12个字符的复杂密码,包括大写字母,小写字母和数字(可选择包括特殊字符)。那些也不应该是字典的一部分。

查看更多:How to securely hash passwords?

答案 1 :(得分:2)

存储密码哈希时,主要假设是使用强力检索密码太困难了。如果您希望它更安全,请使用更慢的哈希算法和更长的密码。

加密比哈希更糟糕,因为哈希是不可逆的,而暴力是检索密码的唯一方法。通过加密,蛮力只是其中一种选择。

一旦清楚,您可以选择在代码中使用“秘密”盐,或者可以使用哈希保存salt。 使用密码保存盐更安全!为什么?因为每个密码都有不同的盐,所以入侵者必须分别强制使用每个密码。如果您有一个全局salt值,则可以一次性对数据库中的所有密码执行强制操作。