web-dev-qa-db-ja.com

bcrypt.checkpwはTypeErrorを返します:チェックする前にUnicodeオブジェクトをエンコードする必要があります

bcrypt.checkpwを呼び出して、暗号化されていないパスワードが認証情報データベースに保存されているハッシュ化されたパスワードと一致するかどうかを確認しますが、

TypeError:チェックする前にUnicodeオブジェクトをエンコードする必要があります

この問題を解決するにはどうすればよいですか?なにか提案を?
python 2.7.6bcrypt 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"、line 100、in checkpw
raise TypeError( "チェックする前に、Unicoedオブジェクトをエンコードする必要があります")
TypeError:チェックする前に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")
18
user7153744

Python 3を使用することを前提としています。Python3では、文字列はデフォルトで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

理由は簡単です。暗号化関数はバイト文字列(または実際には配列)でのみ機能します。

passwordおよびhashed_pa​​sswordは、両方ともバイト文字列である必要があります。

bcrypt.hashpw()関数を使用する場合、hashed_pa​​sswordはバイト文字列でなければならず、問題は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
Laurent LAPORTE

このようにできること

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

簡単です

6
djynnius

私はそのようなものを使います

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