I use this code for hashing and salt:
def make_hash(password):
"""Generate a random salt and return a new hash for the password."""
if isinstance(password, str):
password = password.encode('utf-8')
salt = b64encode(urandom(SALT_LENGTH))
print (salt, type(salt))
#print (salt.encode('utf-8'), type(salt.encode('utf-8')))
return 'PBKDF2${}${}${}${}'.format(
HASH_FUNCTION,
COST_FACTOR,
salt,
b64encode(pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH,
getattr(hashlib, HASH_FUNCTION))))
Here is the pbkdf2_bin:
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac):
h = mac.copy()
h.update(x)
return map(int, h.digest())
buf = []
for block in range(1, -(-keylen // mac.digest_size) + 1):
rv = u = _pseudorandom(salt + _pack_int(block))
for i in range(iterations - 1):
u = _pseudorandom(''.join(map(chr, u)))
rv = starmap(xor, zip(rv, u))
buf.extend(rv)
return ''.join(map(chr, buf))[:keylen]
I already adjusted some things as:
I replaced unicode -> str
I replaced izip -> zip
I changed this map(ord, h.digest()) -> map(int, h.digest())
For python 2 it works fine. I just jumped into python 3.
I am trying to fix this for 2 hours already, all solutions here do not work for me, probably I am missing something. As far as I understand somewhere I need simply to add .encode("utf-8")
But I tryed already to put this everywhere. I thought it must be either the salt
or the x
in h.update(x)
I get the Unicode Objects must be encoded before hashing
in these lines:
EDIT
I found the line where something happens if I encode, but it results in an other error.
u = _pseudorandom(''.join(map(chr, u)).encode("utf-8"))
results in: