2017-04-18 95 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)