在python中使用salt并散列密码
这段代码应该用一个盐来散列密码。 盐和哈希密码正在保存在数据库中。 密码本身不是。
鉴于手术的敏感性,我想确保一切都是洁净的。
注意:我习惯使用b64encode的url安全版本。
import hashlib import base64 import uuid password = 'test_password' salt = base64.urlsafe_b64encode(uuid.uuid4().bytes) t_sha = hashlib.sha512() t_sha.update(password+salt) hashed_password = base64.urlsafe_b64encode(t_sha.digest())
编辑:这个答案是错误的。 不要使用encryption散列来存储密码。 使用密码哈希。
我看起来很好。 不过,我敢肯定你实际上并不需要base64。 你可以这样做:
import hashlib, uuid salt = uuid.uuid4().hex hashed_password = hashlib.sha512(password + salt).hexdigest()
如果不会造成困难,可以通过将salt和散列密码存储为原始字节而不是hexstring来获得稍微更高效的数据库存储。 为此,请使用digest
将hex
和hexdigest
replace为bytes
和hexdigest
。
聪明的事情不是自己写密码,而是使用passlib之类的东西: https ://bitbucket.org/ecollins/passlib/wiki/Home
以安全的方式编写你的encryption代码很容易。 令人讨厌的是,使用非encryption代码时,由于程序崩溃,您无法在工作不正常时立即注意到它。 在使用encryption代码时,通常只会在延迟后发现数据已被泄露。 因此,我认为最好是使用一个由其他人所写的软件包,这个软件包是基于经过testing的协议的主题。
另外,passlib有一些很好的function,使得它易于使用,如果旧的协议被破坏,也很容易升级到一个新的密码哈希协议。
也就是只有一轮sha512更容易受到字典攻击。 sha512被devise得很快,而这在安全地存储密码时实际上是一件坏事。 其他人对所有这些问题都深思熟虑,所以你最好利用这一点。
基于这个问题的其他答案,我已经实现了一个使用bcrypt的新方法。
为什么使用bcrypt
如果我理解正确,在SHA512
上使用bcrypt
的参数是bcrypt
被devise得很慢。 bcrypt
还有一个选项,可以在第一次生成哈希密码时调整你想要的速度:
# The '12' is the number the dictates the 'slowness' bcrypt.hashpw(password, bcrypt.gensalt( 12 ))
缓慢是可取的,因为如果恶意的一方在包含散列密码的表上得到他们的手,则解密它们变得更加困难。
履行
def get_hashed_password(plain_text_password): # Hash a password for the first time # (Using bcrypt, the salt is saved into the hash itself) return bcrypt.hashpw(plain_text_password, bcrypt.gensalt()) def check_password(plain_text_password, hashed_password): # Check hased password. Useing bcrypt, the salt is saved into the hash itself return bcrypt.checkpw(plain_text_password, hashed_password)
笔记
我能够很容易地在Linux系统中安装库,使用:
pip install py-bcrypt
不过,我在安装Windows系统时遇到了更多麻烦。 它似乎需要一个补丁。 看到这个Stackoverflow的问题: py-bcrypt安装在win 7 64bit python上
为了在Python 3中工作,你需要以UTF-8编码为例:
hashed_password = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()
否则,你会得到:
回溯(最近一次通话最后):
文件“”,第1行,
hashed_password = hashlib.sha512(密码+ salt).hexdigest()
TypeError:Unicode对象必须在散列之前进行编码
如果您需要使用现有系统存储的散列,passlib似乎很有用。 如果你有格式的控制,使用像bcrypt或scrypt的现代散列。 在这个时候,bcrypt似乎更容易使用python。
passlib支持bcrypt,build议安装py-bcrypt作为后端: http : //pythonhosted.org/passlib/lib/passlib.hash.bcrypt.html
如果你不想安装passlib,你也可以直接使用py-bcrypt 。 自述文件具有基本使用的示例。
另请参阅: 如何使用scrypt在Python中为密码和salt生成哈希
我不想复活一个旧的线程,但是任何想要使用现代最新安全解决scheme的人都可以使用argon2。
https://pypi.python.org/pypi/argon2_cffi
它赢得了密码哈希比赛。 ( https://password-hashing.net/ )比bcrypt更容易使用,比bcrypt更安全。