用Python编写密码

2024-05-20 00:00:59 发布

您现在位置:Python中文网/ 问答频道 /正文

这段代码应该用盐来散列密码。salt和散列密码将保存在数据库中。密码本身不是。

鉴于这次行动的敏感性,我想确保一切都是清正廉洁的。

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())

Tags: 代码testimport数据库密码uuidpasswordhashlib
3条回答

编辑:此答案错误。SHA512的单个迭代是fast,这使得它不适合用作密码散列函数。在这里使用其他答案之一。


我觉得很好。不过,我很确定你实际上并不需要base64。你可以这样做:

import hashlib, uuid
salt = uuid.uuid4().hex
hashed_password = hashlib.sha512(password + salt).hexdigest()

如果不造成困难,您可以将salt和散列密码存储为原始字节而不是十六进制字符串,从而在数据库中获得稍微更高效的存储。为此,用bytes替换hex,用digest替换hexdigest

基于这个问题的其他答案,我使用bcrypt实现了一种新的方法。

为什么使用bcrypt

如果我理解正确,在SHA512上使用bcrypt的参数是bcrypt被设计为慢。bcrypt还有一个选项,可以在第一次生成散列密码时调整希望的速度:

# The '12' is the number that 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 hashed password. Using bcrypt, the salt is saved into the hash itself
    return bcrypt.checkpw(plain_text_password, hashed_password)

注释

我可以很容易地在linux系统中安装库,使用:

pip install py-bcrypt

但是,我在windows系统上安装它时遇到了更多的问题。它似乎需要一个补丁。请参阅此堆栈溢出问题:py-bcrypt installing on win 7 64bit python

聪明的做法不是自己写密码,而是使用passlib:https://bitbucket.org/ecollins/passlib/wiki/Home之类的东西

以安全的方式编写密码很容易出错。最糟糕的是,对于非加密代码,自从程序崩溃以来,当它不工作时,您常常会立即注意到它。而使用加密代码时,你通常只会在迟到和你的数据被泄露后才发现。因此,我认为最好使用一个由其他人编写的包,这个包是由对这个主题有一定了解的人编写的,并且是基于经过战斗测试的协议的。

passlib还有一些很好的特性,这些特性使它易于使用,并且如果旧的协议被破坏了,也很容易升级到新的密码散列协议。

另外,单轮sha512更容易受到字典攻击。sha512的设计速度很快,在试图安全存储密码时,这实际上是一件坏事。其他人对这类问题考虑了很久,所以你最好利用这一点。

相关问题 更多 >