web-dev-qa-db-fra.com

bcrypt.checkpw renvoie TypeError: les objets Unicode doivent être codés avant la vérification

J'appelle bcrypt.checkpw pour vérifier que le mot de passe non chiffré correspond au mot de passe haché stocké dans la base de données d'informations d'identification, mais recevoir

TypeError: les objets Unicode doivent être codés avant la vérification

Comment dois-je résoudre ce problème? Toute suggestion?
J'ai installé python 2.7.6, et bcrypt 3.1.1

J'ai le code suivant:

def check_password(password, hashed_password)
    if not bcrypt.checkpw(password, hashed_password):
        raise InvalidCredentials("403 Forbidden")
    else:
        return true

Et recevez l'erreur suivante:

Fichier "/home/qt/virtualenv/lib/python2.7/site-packages/bcrypt/init.py", ligne 100, dans checkpw
raise TypeError ("Les objets Unicoed doivent être encodés avant vérification")
TypeError: les objets Unicode doivent être codés avant la vérification

J'ai examiné bcrypt/__init__.py, mais je ne sais pas pourquoi

def checkpw(password, hashed_password):    
    if (isinstance(password, six.text_type) or            
        isinstance(hashed_password, six.text_type)):        
    raise TypeError("Unicode-objects must be encoded before checking")
18
user7153744

Je fais l'hypothèse que vous utilisez Python 3. Avec Python 3, les chaînes sont, par défaut, des chaînes unicode.

Si vous appelez la fonction bcrypt.checkpw() avec des valeurs unicode:

import bcrypt

password = "seCr3t"  # unicode string
hashed_password = "hashed_seCr3t"  # unicode string

bcrypt.checkpw(password, hashed_password)

Vous obtiendrez cette exception

Traceback (most recent call last):
  ...
TypeError: Unicode-objects must be encoded before checking

La raison est simple: les fonctions cryptographiques ne fonctionnent que sur des chaînes d'octets (ou des tableaux en fait).

Vous mot de passe et hashed_password devez être des chaînes de deux octets.

Si vous utilisez la fonction bcrypt.hashpw(), votre hashed_password doit être une chaîne d'octets, et je pense que le problème est pour le mot de passe valeur. Ce mot de passe doit provenir d'une forme HTML de quelque chose de similaire. Pour utiliser la fonction bcrypt.checkpw(), vous devez d'abord encoder la valeur de chaîne en utilisant le même encodage que vous utilisez pour crypter le mot de passe avec le bcrypt.hashpw() fonction. Habituellement, nous choisissons l'encodage "utf8".

Par exemple (Python 2 & 3):

import bcrypt

# at creation first:
password = u"seCr3t"
hashed_password = bcrypt.hashpw(password.encode('utf8'), bcrypt.gensalt())

# first attempt:
password = u"seCrEt"
bcrypt.checkpw(password.encode('utf8'), hashed_password)
# -> False

# second attempt:
password = u"seCr3t"
bcrypt.checkpw(password.encode('utf8'), hashed_password)
# -> True

Voir utilisation simple sur page Gihub

14
Laurent LAPORTE

Quelque chose que tu pourrais faire comme ça

bcrypt.checkpw(password.encode('utf-8'), hashed_password.encode('utf-8'))

c'est simple

6
djynnius

j'utilise quelque chose comme ça

class User(Base):
    __tablename__ = "user"
    id = Column(BigInteger, primary_key=True, autoincrement=True)

    login = Column(String, nullable=False, unique=True)
    password = Column(String, nullable=False)

    @staticmethod
    def make_password_hash(password):
        hash = bcrypt.hashpw(password=password.encode('utf-8'), salt=bcrypt.gensalt())
        return hash.decode('utf-8')

    def is_password_valid(self, password):
        return bcrypt.checkpw(password.encode('utf-8'), self.password.encode('utf-8'))
2
Gosha null