Python bcrypt.checkpw返回TypeError:在检查之前必须对Unicode对象进行编码

Python bcrypt.checkpw返回TypeError:在检查之前必须对Unicode对象进行编码,python,bcrypt,Python,Bcrypt,我正在调用bcrypt.checkpw检查未加密的密码与凭证数据库中存储的哈希密码是否匹配,但收到 TypeError:检查前必须对Unicode对象进行编码 我应该如何解决这个问题?有什么建议吗? 我安装了python2.7.6,以及bcrypt 3.1.1 我有以下代码: def check_password(password, hashed_password) if not bcrypt.checkpw(password, hashed_password): rai

我正在调用
bcrypt.checkpw
检查未加密的密码与凭证数据库中存储的哈希密码是否匹配,但收到

TypeError:检查前必须对Unicode对象进行编码

我应该如何解决这个问题?有什么建议吗?
我安装了
python2.7.6
,以及
bcrypt 3.1.1

我有以下代码:

def check_password(password, hashed_password)
    if not bcrypt.checkpw(password, hashed_password):
        raise InvalidCredentials("403 Forbidden")
    else:
        return true
并接收以下错误:

文件“/home/qt/virtualenv/lib/python2.7/site packages/bcrypt/init.py”,第100行,在checkpw
raise TypeError(“检查前必须对Unicode对象进行编码”)
TypeError:检查前必须对Unicode对象进行编码

我查看了
bcrypt/\uuu init\uuuu.py
,但我不知道为什么

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")

我假设您使用Python 3。对于Python3,默认情况下,字符串是unicode字符串

如果使用unicode值调用
bcrypt.checkpw()
函数:

import bcrypt

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

bcrypt.checkpw(password, hashed_password)
你会得到这个例外

Traceback (most recent call last):
  ...
TypeError: Unicode-objects must be encoded before checking
原因很简单:加密函数只对字节字符串(或者实际上是数组)起作用

密码和哈希密码必须都是字节字符串

如果使用
bcrypt.hashpw()
函数,则哈希密码必须是字节字符串,我认为问题在于密码值。此密码必须来自类似的HTML表单。要使用
bcrypt.checkpw()
函数,必须首先使用与使用
bcrypt.hashpw()函数加密密码相同的编码对字符串值进行编码。通常,我们选择“utf8”编码

例如(Python 2和3):


请参见您可以这样做的一些操作的简单用法

bcrypt.checkpw(password.encode(), hashed_password)

简单吗

我用的是这样的东西

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'))

使用类似的方法,例如,查看代码下面的注释:

import bcrypt

def comparacaoSenha(passw, hash):
    if bcrypt.checkpw(passw, hash):
        print("It Matches!")
    else:
            print("It Does not Match")

password = "super secret password".encode('utf-8')
password2 = "another password".encode('utf-8')

hashed = bcrypt.hashpw(password, bcrypt.gensalt())
heashed2 = bcrypt.hashpw(password2, bcrypt.gensalt())

print("Teste 1: ")
print("-----------------------------")
print("PASSWORD: ", password)
print("HASHED PW: ", hashed)
comparacaoSenha(password, hashed)
print("-----------------------------")

print("Teste 2: ")
print("-----------------------------")
print("PASSWORD: ", password2)
print("HASHED PW: ", heashed2)
comparacaoSenha(password2, heashed2)
print("-----------------------------")

# Things to remember:
# always use the encode('utf-8') or put a prefix 'b'' just before the strings
# EX: newPass = b"OTHER PASSWORD" // or newPass="OTHER PASSWORD".encode('utf-8')
# 

感谢Laurent的快速响应和清晰的代码示例!我正在使用python 2.7.6。我试过你的建议,它毫无错误地起作用。我假设字符串在默认情况下也是使用Python2.7.6的unicode字符串。不,Python2在默认情况下使用字节字符串。如果需要unicode字符串,则需要使用如下“u”前缀:
u“foo”
,或者使用
decode()
方法将字节字符串转换为unicode。unicode字符串应该来自HTML表单或类似的输入:这是典型的(也是预期的)行为。我将examle更改为Python 2和3 compatibleHmm。因此,对于Python 2,我的原始代码应该可以工作,因为密码和哈希密码都是字节字符串。那我为什么会在这种情况下得到例外呢?password=“seCr3t”#bytes strings hashed_password=“hashed_seCr3t”#bytes string bcrypt.checkpw(password,hashed_password)@user7153744:原始异常消息很清楚:您至少有一个Unicode值(必须进行编码)。现在,这会抛出错误
AttributeError:“bytes”对象没有属性“encode”
这应该可以工作:bcrypt.checkpw(password.encode('utf-8'),hash_password)。将更新答案
import bcrypt

def comparacaoSenha(passw, hash):
    if bcrypt.checkpw(passw, hash):
        print("It Matches!")
    else:
            print("It Does not Match")

password = "super secret password".encode('utf-8')
password2 = "another password".encode('utf-8')

hashed = bcrypt.hashpw(password, bcrypt.gensalt())
heashed2 = bcrypt.hashpw(password2, bcrypt.gensalt())

print("Teste 1: ")
print("-----------------------------")
print("PASSWORD: ", password)
print("HASHED PW: ", hashed)
comparacaoSenha(password, hashed)
print("-----------------------------")

print("Teste 2: ")
print("-----------------------------")
print("PASSWORD: ", password2)
print("HASHED PW: ", heashed2)
comparacaoSenha(password2, heashed2)
print("-----------------------------")

# Things to remember:
# always use the encode('utf-8') or put a prefix 'b'' just before the strings
# EX: newPass = b"OTHER PASSWORD" // or newPass="OTHER PASSWORD".encode('utf-8')
#