2017-04-18 83 views
0

我试图迁移以下到Python 3随机盐串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)     

回答

2

您可以使用.encode()将一个字符串对象转换为字节。

salt = salt.encode('utf-8') 

但你不应该

random模块不会产生密码安全的随机数。这会在代码中留下漏洞。如果你使用Python 3.6,secrets模块更好。

salt = secrets.token_bytes(16) 

如果没有,os.urandom()也记载为“用于加密应用程序提供足够不可预测的”。

salt = os.urandom(16)