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

use*_*744 12 python bcrypt

我打电话bcrypt.checkpw检查未加密的密码匹配与存储在凭证数据库中的散列密码,但接收

TypeError:必须在检查之前对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
Run Code Online (Sandbox Code Playgroud)

并收到以下错误:

文件"/home/qt/virtualenv/lib/python2.7/site-packages/bcrypt/ init .py",第100行,在checkpw
引发TypeError("Unicoed-objects必须在检查之前编码")
TypeError:Unicode-objects必须在检查前进行编码

我调查了一下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")
Run Code Online (Sandbox Code Playgroud)

Lau*_*RTE 15

我假设你使用Python 3.在Python 3中,字符串默认是unicode字符串.

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

import bcrypt

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

bcrypt.checkpw(password, hashed_password)
Run Code Online (Sandbox Code Playgroud)

你会得到这个例外

Traceback (most recent call last):
  ...
TypeError: Unicode-objects must be encoded before checking
Run Code Online (Sandbox Code Playgroud)

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

您的密码hashed_pa​​ssword必须都是字节字符串.

如果你使用这个bcrypt.hashpw()函数,你的hashed_pa​​ssword必须是一个字节字符串,我认为问题是密码值.此密码必须来自类似的HTML表单.要使用该bcrypt.checkpw()功能,必须首先使用与该功能加密密码相同的编码对字符串值进行编码bcrypt.hashpw().通常,我们选择'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
Run Code Online (Sandbox Code Playgroud)

请参阅Gihub页面上的简单用法

  • 不,Python 2 默认使用字节字符串。如果你想要 unicode 字符串,你需要像这样使用“u”前缀:`u"foo"`,或者使用 `decode()` 方法将字节字符串转换为 unicode。unicode 字符串应该来自您的 HTML 表单或类似的输入:这是经典的(和预期的)行为。 (2认同)

小智 6

你可以这样做

bcrypt.checkpw(password.encode('utf-8'), hashed_password.encode('utf-8'))
Run Code Online (Sandbox Code Playgroud)

简单吗


Gos*_*ull 6

我使用类似的东西

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'))
Run Code Online (Sandbox Code Playgroud)