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

问题描述 投票:0回答:5

我正在调用

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

类型错误:在检查之前必须对 Unicode 对象进行编码

我该如何解决这个问题?有什么建议吗?
我安装了

python 2.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(“在检查之前必须对 Unicoed 对象进行编码”)
类型错误:在检查之前必须对 Unicode 对象进行编码

我调查了

bcrypt/__init__.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 bcrypt
5个回答
36
投票

我假设您使用 Python 3。使用 Python 3,字符串默认为 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

原因很简单:加密函数仅适用于字节字符串(或实际上是数组)。

passwordhashed_password 必须都是字节字符串。

如果您使用

bcrypt.hashpw()
函数,您的 hashed_password 必须是字节字符串,我认为问题在于 password 值。这个password必须来自类似的HTML形式。要使用
bcrypt.checkpw()
函数,您必须首先使用与使用 bcrypt.hashpw() 函数加密
password
相同的编码对字符串值进行编码。通常,我们选择“utf8”编码。

例如(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

Gihub页面上查看简单用法


14
投票

你可以这样做

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

简单易行


9
投票

我用类似的东西

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

0
投票

使用它,例如并查看代码下面的注释:

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

0
投票

我遇到了同样的错误,这是解决方案 在检查之前必须先编码后解码 hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')

如果用户和bcrypt.checkpw(password.encode('utf8'), user.password.encode('utf-8')):

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.