gamer
gamer

Reputation: 5863

Python unicode object must be encoded before hashing

I am trying to hash some random string:

key = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
salt = hashlib.sha1(key).hexdigest()[:5].encode('utf-8')            
activation_key = hashlib.sha1(salt+email).hexdigest() 

When I do this it says unicode object must be encoded before hashing:

Traceback (most recent call last):
  # lines omitted..
  File <something>, line <digits>, in <module name>
    salt = hashlib.sha1(key).hexdigest()[:5].encode('utf-8')            
TypeError: Unicode-objects must be encoded before hashing

Whats wrong in here? I have even encoded key.

Upvotes: 1

Views: 1786

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121226

Your key and email objects are Unicode values too. You'll have to encode those:

key = ''.join(random.choice(string.ascii_lowercase) for i in range(10))
salt = hashlib.sha1(key.encode('ascii')).hexdigest()[:5]           
activation_key = hashlib.sha1((salt + email).encode('utf8')).hexdigest() 

I'm not sure why you are first hashing the random salt key here, however; you are limiting the salt value now by taking the first 5 hexadecimal digits, limiting yourself to the letters a-f and numbers 0-9.

Just use a random string without further hashing, but perhaps expand the number of possible characters. Encode them up-front even:

salt_bytes = (string.ascii_letters + string.digits).encode('ascii')
salt = bytes([random.choice(salt_bytes) for _ in range(5)])
activation_key = hashlib.sha1(salt + email.encode('utf8')).hexdigest() 

Then again, if this is to be an activation key, unless you store the random salt somewhere separate you can never recreate that key from the email address alone. You may as well use 40 random string.hexdigits characters to generate that key.

Upvotes: 1

Related Questions