Проверка пароля с ошибками в символах £ или $ с использованием passlib

Я использую passlib==1.7.1 со следующим импортом:

from passlib.apps import custom_app_context as pwd_context

Затем хэшируйте пароль следующим образом:

pwd_context.encrypt(password)

Затем я проверяю с помощью:

pwd_context.verify(password, self.password_hash)

Это нормально, но проверка не проходит с определенными символами. например, "£" или "$".

Кто-нибудь знает, почему это так, пожалуйста?

Спасибо!


Обновить:

Спасибо всем большое. Вооружившись этой информацией, я исследовал немного больше, и кажется, что проблема не в passlib, а где-то между angular4, где я отправляю заголовок авторизации base64 в приложение фляги.

В настоящее время я использую следующее, чтобы сделать это:

let headers: Headers = new Headers({
        'Content-Type': 'application/json',
        'Authorization': 'Basic ' + btoa(userLoginRequest.username + ':' + userLoginRequest.password)
    });

Сегодня я много читал о unescape (и это обесценивает в пользу decodeURI()). Я также много читал о поддержке юникода в кодировке base64. Я попробовал несколько комбинаций этих вещей, и это не имело никакого значения. Я сейчас очень запутался!

Чтобы проверить, что происходит, я делаю следующее. В angular4 я выполняю следующее:

let encodedString = btoa('doug:Tree£9')
console.log(encodedString)
console.log(atob(encodedString))

Как и ожидалось, это выводит на консоль следующее.

ZG91ZzpUcmVlozk=
doug:Tree£9

Так что это нормально кодирование и декодирование.

Делать тот же процесс в Python...

import base64
encoded = base64.b64encode('doug:Tree£9')
print encoded
print base64.b64decode(encoded)

Я получаю следующее в терминале.

ZG91ZzpUcmVlwqM5
doug:Tree£9

Я отмечаю, что "ZG91ZzpUcmVlozk=" и "ZG91ZzpUcmVlwqM5" не совпадают. Тем не менее, оба метода работают на своих языках.

Если я вставлю закодированную строку "ZG91ZzpUcmVlozk=" из javascript в python и расшифрую ее следующим образом...

import base64
print base64.b64decode("ZG91ZzpUcmVlozk=")

Я получил:

doug:Tree�9

Обратите внимание, что символ "£" теперь разомкнут.

Другие символы Юникода тоже терпят неудачу.

Поэтому я думаю, что вопрос заключается в том, как мне закодировать заголовок Авторизация, чтобы python правильно распознавал символ £, а любые другие пользователи символов выбирали свои пароли?

Спасибо!


Изменить: Решено!

Я обнаружил, что использование atob Javascript для декодирования base64 некорректно декодирует строки utf-8, что вдавалось в некоторые детали. Я решил это, используя следующий подход, рекомендованный @brandonscript.

b64EncodeUnicode(str) : string{
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode(parseInt(p1, 16))
    }))
}

Работает отлично! Уф!

2 ответа

# -*- coding: utf-8 -*-
from passlib.apps import custom_app_context as pwd_contex

password='£$'

encrypted=pwd_contex.encrypt(password)

print(pwd_contex.verify('£$', encrypted))
print(pwd_contex.verify('john', encrypted))

True
False

отлично работает в моей системе. Возможно, вам нужно установить кодировку по умолчанию # -*- coding: utf-8 -*- в верхней части вашего сценария

Я предполагаю, что вы столкнулись с проблемой кодировки, из документации,

http://passlib.readthedocs.io/en/stable/narr/hash-tutorial.html

Используйте PasswordHash.hash() для хэширования пароля. Этот вызов заботится о кодировке Unicode....

from passlib.hash import pbkdf2_sha256

hash = pbkdf2_sha256.hash("$password")
pbkdf2_sha256.verify("$password", hash)
# True
Другие вопросы по тегам