Как расшифровать значение на другом сервисе, на котором оно было первоначально зашифровано с помощью Fernet?
Я работаю над проектом, который основан на бэкенде на python. У меня будет Django для "основных" вещей и FastAPI для некоторых краулеров. Я зашифровываю некоторые данные в БД с помощью Django, используя модуль Fernet
и пользовательский Field
.
class EncryptedField(models.CharField):
description = "Save encrypted data to DB an read as string on application level."
def __init__(self, *args, **kwargs):
kwargs["max_length"] = 1000
super().__init__(*args, **kwargs)
@cached_property
def fernet(self) -> Fernet:
return Fernet(key=settings.FERNET_KEY)
def get_internal_type(self) -> str:
return "BinaryField"
def get_db_prep_save(
self, value: Any, connection: BaseDatabaseWrapper
) -> Union[memoryview, None]:
value = super().get_db_prep_save(value, connection)
if value is not None:
encrypted_value = self.fernet.encrypt(data=force_bytes(s=value))
return connection.Database.Binary(encrypted_value)
def from_db_value(self, value: bytes, *args) -> Union[str, None]:
if value is not None:
decrypted_value = self.fernet.decrypt(token=force_bytes(s=value))
return self.to_python(value=force_str(s=decrypted_value))
Все работает как ожидалось, проблема возникает, когда я пытаюсь расшифровать значение на стороне FastAPI:
def decrypt(value: bytes):
return Fernet(FERNET_KEY).decrypt(token=value)
Некоторая важная информация:
- Я дважды проверяю и
settings.FERNET_KEY == FERNET_KEY
, т.е. я использую один и тот же ключ с обеих сторон. - Оба сервиса используют одну и ту же БД, а функция получает разные значения при чтении для нее.
- Django ->
from_db_value
->value
->b"gAAAAABhSm94ADjyQES3JL-EiEX4pH2odwJnJe2qsuGk_K685vseoVNN6kuoF9CRdf2GxiIViOgiKVcZMk5olg7FrJL2cmMFvg=="
- FastAPI ->
from_db_value
->value
->b"pbkdf2_sha256$260000$RzIJ5Vg3Yx8JTz4y5ZHttZ$0z9CuQiPCJrBZqc/5DvxiEcbNHZpu8hAZgmibAe7nrQ="
. Я действительно вошел в БД и проверил, что это то значение, которое там хранится.
- Django ->
Поэтому я задаюсь вопросом, есть ли что-то перед from_db_value
, что как-то преобразует значение?!
Одной из последних альтернатив может быть расшифровка значения на Django и отправка его непосредственно в FastAPI, но я бы предпочел этого не делать.
Как расшифровать значение на FastAPI?
В FastAPI нет принудительной обработки байтов.
def decrypt(value: bytes):
return Fernet(FERNET_KEY).decrypt(token=value)
#instead do
def decrypt(value: bytes):
return Fernet(FERNET_KEY).decrypt(token=force_bytes(s=value))
Тогда функция расшифровки на Django и FastAPI будет выглядеть одинаково. Force_bytes может быть местом, где данные изменяются.
Я бы рекомендовал вам проверить функцию force bytes. Если возможно, покажите нам код в функции force bytes.
Достаточно расшифровать значение:
def decrypt(value: bytes):
return Fernet(FERNET_KEY).decrypt(token=value)
Вы уверены, что пытаетесь расшифровать одни и те же данные? Для меня это выглядит как зашифрованное поле пароля и какое-то другое поле.
mysql> select first_name, password from users_user where login='test'
+------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------+
| first_name | password |
| gAAAAABhSm94ADjyQES3JL-EiEX4pH2odwJnJe2qsuGk_K685vseoVNN6kuoF9CRdf2GxiIViOgiKVcZMk5olg7FrJL2cmMFvg== | pbkdf2_sha256$260000$RzIJ5Vg3Yx8JTz4y5ZHttZ$0z9CuQiPCJrBZqc/5DvxiEcbNHZpu8hAZgmibAe7nrQ= |