22
votes

I'm trying to store salt and hashed password before inserting each document into a collection. But on encoding the salt and password, it shows the following error:

 line 26, in before_insert
 document['salt'] = bcrypt.gensalt().encode('utf-8')

AttributeError: 'bytes' object has no attribute 'encode'

This is my code:

def before_insert(documents):
    for document in documents:
        document['salt'] = bcrypt.gensalt().encode('utf-8')
        password = document['password'].encode('utf-8')
        document['password'] = bcrypt.hashpw(password, document['salt'])

I'm using eve framework in virtualenv with python 3.4

2
Did you try not encode-ing it? - jonrsharpe
Yes, if i just use document['salt'] = bcrypt.gensalt() it shows "in hashpw raise TypeError("Unicode-objects must be encoded before hashing") TypeError: Unicode-objects must be encoded before hashing" @jonrsharpe - DEVV911
It looks like bcrypt is returning a bytes instance, which cannot be encoded. It can be decoded if needed. Encoding = str to bytes, decoding = bytes to str. – What exactly is complaining with a TypeError where exactly? - deceze♦
It shows TypeError at bcrypt.hashpw and it says Unicode-objects must be encoded before hashing - DEVV911
XYProblem? Your issue isn't that you can't encode the result of bcrypt.gensalt(). You definitely cannot, it's already a bytes object. Your issue is that there's somehow a unicode object in bcrypt.hashpw! - MisterMiyagi

2 Answers

5
votes

You're using :

bcrypt.gensalt()
.encode('utf-8')

Bytes description in python 3 documentation

1
votes

The salt from the .getsalt() method is a bytes object, and all the "salt" parameters in the methods of bcrypt module expect it in this particular form. There is no need to convert it to something else.

In contrast to it, the "password" parameters in methods of bcrypt module are expected it in the form of the Unicode string - in Python 3 it is simply a string.

So - assuming that your original document['password'] is a string, your code should be

def before_insert(documents):
    for document in documents:
        document['salt'] = bcrypt.gensalt()
        password = document['password']
        document['password'] = bcrypt.hashpw(password, document['salt'])