Проверка пароля с ошибками в символах £ или $ с использованием 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