Python 3 中的随机盐字符串
random salt string in Python 3
我正在尝试将以下内容迁移到 Python 3.
def mkhash(password, salt=None):
"""
Compute SHA256 hash of password with pbkdf2 algorithm.
Call with salt=None for creating hash. To compute verification
hash, supply salt stored in the user's row in auth_user.
Args:
password :
salt=None :
Returns: tuple (hash, salt)
Raises: Nothing
"""
if salt is None:
## use a 16 char random string
randchars = [random.choice(string.ascii_lowercase) for _ in range(16)]
#salt = b''.join(randchars)# works in 2 but not 3
salt = ''.join(randchars) # works in 3 but result fails in hashlib call
# See https://docs.python.org/2/library/hashlib.html
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 10000)
pwhash = binascii.hexlify(dk)
return (pwhash, salt)
这是 Python 3.
中失败的回溯
Traceback (most recent call last):
File "auth.py", line 451, in <module>
_ = mkhash('badpassword')
File "auth.py", line 146, in mkhash
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 10000)
TypeError: a bytes-like object is required, not 'str'
在 Python 3 中,生成与 hashlib 函数兼容的长度为 N 的盐的正确方法是什么?
编辑:使用已接受答案的工作版本:
def mkhash(password, salt=None):
"""
Compute SHA256 hash of password with pbkdf2 algorithm.
Call with salt=None for creating hash. To compute verification
hash, supply salt stored in the user's row in auth_user.
Args:
password :
salt=None :
Returns: tuple (hash, salt)
Raises: Nothing
"""
if salt is None:
salt = os.urandom(16)
elif type(salt) is not bytes:
salt = salt.encode('utf-8')
# See https://docs.python.org/3/library/hashlib.html
dk = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 10000)
pwhash = binascii.hexlify(dk)
return (pwhash, salt)
您可以使用 .encode()
将字符串对象转换为字节。
salt = salt.encode('utf-8')
但是你不应该。
random
模块不生成加密安全随机数。这会在您的代码中留下一个漏洞。如果您使用 Python 3.6,secrets
模块更好。
salt = secrets.token_bytes(16)
如果不是,os.urandom()
也被记录为 "unpredictable enough for cryptographic applications"。
salt = os.urandom(16)
我正在尝试将以下内容迁移到 Python 3.
def mkhash(password, salt=None):
"""
Compute SHA256 hash of password with pbkdf2 algorithm.
Call with salt=None for creating hash. To compute verification
hash, supply salt stored in the user's row in auth_user.
Args:
password :
salt=None :
Returns: tuple (hash, salt)
Raises: Nothing
"""
if salt is None:
## use a 16 char random string
randchars = [random.choice(string.ascii_lowercase) for _ in range(16)]
#salt = b''.join(randchars)# works in 2 but not 3
salt = ''.join(randchars) # works in 3 but result fails in hashlib call
# See https://docs.python.org/2/library/hashlib.html
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 10000)
pwhash = binascii.hexlify(dk)
return (pwhash, salt)
这是 Python 3.
中失败的回溯Traceback (most recent call last):
File "auth.py", line 451, in <module>
_ = mkhash('badpassword')
File "auth.py", line 146, in mkhash
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 10000)
TypeError: a bytes-like object is required, not 'str'
在 Python 3 中,生成与 hashlib 函数兼容的长度为 N 的盐的正确方法是什么?
编辑:使用已接受答案的工作版本:
def mkhash(password, salt=None):
"""
Compute SHA256 hash of password with pbkdf2 algorithm.
Call with salt=None for creating hash. To compute verification
hash, supply salt stored in the user's row in auth_user.
Args:
password :
salt=None :
Returns: tuple (hash, salt)
Raises: Nothing
"""
if salt is None:
salt = os.urandom(16)
elif type(salt) is not bytes:
salt = salt.encode('utf-8')
# See https://docs.python.org/3/library/hashlib.html
dk = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 10000)
pwhash = binascii.hexlify(dk)
return (pwhash, salt)
您可以使用 .encode()
将字符串对象转换为字节。
salt = salt.encode('utf-8')
但是你不应该。
random
模块不生成加密安全随机数。这会在您的代码中留下一个漏洞。如果您使用 Python 3.6,secrets
模块更好。
salt = secrets.token_bytes(16)
如果不是,os.urandom()
也被记录为 "unpredictable enough for cryptographic applications"。
salt = os.urandom(16)