在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来获得稍微更高效的数据库存储。 为此,请使用digesthexhexdigestreplace为byteshexdigest

聪明的事情不是自己写密码,而是使用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_pa​​ssword = 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更安全。