【发布时间】:2012-03-24 13:07:25
【问题描述】:
此代码应该使用盐对密码进行哈希处理。盐和散列密码被保存在数据库中。密码本身不是。
鉴于操作的敏感性,我想确保一切都符合犹太教规。
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())
【问题讨论】:
-
你为什么要对盐进行 b64 编码?直接使用盐然后 b64 将两者一起编码
t_sha.digest() + salt会更简单。当您解码盐分哈希密码后,您可以再次拆分盐分,因为您知道解码后的哈希密码正好是 32 个字节。 -
@Duncan - 我对 salt 进行了 base64 编码,因此我可以对其进行强大的操作,而不必担心奇怪的问题。 “字节”版本会作为字符串工作吗?如果是这种情况,那么我也不需要 base64 编码 t_sha.digest() 。我可能不会将散列密码和 salt 保存在一起,因为这看起来有点复杂且可读性差一些。
-
如果您使用的是 Python 2.x,那么 bytes 对象将作为字符串很好地工作。 Python 对字符串中可以包含的内容没有任何限制。但是,如果您将字符串传递给任何外部代码(例如数据库),则可能不适用。 Python 3.x 区分了字节类型和字符串,因此在这种情况下,您不希望在 salt 上使用字符串操作。
-
我不能告诉你如何在 python 中做到这一点,但普通的 SHA-512 是一个糟糕的选择。使用慢速散列,例如 PBKDF2、bcrypt 或 scrypt。
-
旁注:我建议不要使用 UUID 作为加密随机性的来源。是的,CPython is cryptographically secure 使用的实现,但这不是由 Python 的规范 nor the UUID spec 和 vulnerable implementations exist 规定的。如果您的代码库在没有安全 UUID4 的情况下使用 Python 实现运行,您将削弱安全性。这可能不太可能发生,但改用
secrets并不需要任何成本。
标签: python authentication hash passwords salt