Если вы используете класс Fernet, предоставляемый пакетом cryptography python, вам необходимо кодировать ваш ключ как base64, а не декодировать его перед передачей. Кодировка преобразуется в указанную форму,декодирование преобразуется из указанной формы. В настоящее время вы конвертируете exit_care
в ascii (не обязательно), вычисляете хеш md5, получаете шестнадцатеричное представление и снова конвертируете его в ascii.Затем ваша программа пытается интерпретировать этот шестнадцатеричный-> ascii md5 хэш как строку в кодировке base64 при использовании base64.urlsafe_b64decode(key)
.Это точка отказа на данный момент.Скорее всего, вы хотите использовать base64.urlsafe_b64encode(key)
вместо того, чтобы конвертировать его в base64, необходимый для использования Fernet.
Возможно вам может потребоваться заполнить его до 32 байтов , как предполагает документация Fernet https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet
Параметры: ключ (байты) - URL-безопасный base64-кодированный 32-байтовый ключ.Это должно быть в секрете.Любой, у кого есть этот ключ, может создавать и читать сообщения.
Это связано с тем, что MD5 создаст 128-битное значение, которое закодировано как 22-символьная строка base64 (фактически 24, потому что python автоматически добавляет ккратный 4).См. https://stackoverflow.com/a/13296298/6269138 о том, почему это так.Рассматривая реализацию Fernet, они проверяют длину строки в 64-битной кодировке, чтобы увидеть, равна ли она длине 32, и выдают ошибку, если это не так. Вы можете набрать правую клавишу с помощью =
, если хотите, или использовать алгоритм генерации / растягивания ключа, описанный ниже.
Я рекомендую использовать настройку, аналогичную настройкев документации Fernet пакета python для криптографии, найденного здесь https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet для растягивания ключа.Код со страницы вставлен ниже, заменяя PBKDF2HMAC на HKDF, поскольку первый требует соли и, вероятно, излишним в этой ситуации, если вы не храните пароли в производственной базе данных.
>>> import base64
>>> import os
>>> from cryptography.fernet import Fernet
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
>>> password = b"password"
>>> hkdf = HKDF(
... algorithm=hashes.SHA256(), # You can swap this out for hashes.MD5()
... length=32,
... salt=None, # You may be able to remove this line but I'm unable to test
... info=None, # You may also be able to remove this line
... backend=default_backend()
... )
>>> key = base64.urlsafe_b64encode(hkdf.derive(password))
>>> f = Fernet(key)
>>> token = f.encrypt(b"Secret message!")
>>> token
b'...'
>>> f.decrypt(token) # Process the key in the exact same manner to decode an encoded message
b'Secret message!'