我正在玩一个基于 python 后端的项目。我将 Django 用于“核心”内容,FastAPI 用于一些爬虫。Fernet
我正在使用模块和自定义的 Django 将一些数据加密到数据库中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=="
- 快速API ->
user.encrypted_field
->value
->b"pbkdf2_sha256$260000$RzIJ5Vg3Yx8JTz4y5ZHttZ$0z9CuQiPCJrBZqc/5DvxiEcbNHZpu8hAZgmibAe7nrQ="
。我实际上进入了数据库并检查了这是存储在那里的值。user
来自这里:-
from sqlmodel import Session, select from .models import User async def get_user(db: Session, username: str) -> str: statement = select(User).where(User.username == username) return db.exec(statement).first()
-
- Django ->
所以我想知道在from_db_value
以某种方式转换价值之前有什么东西?!
最后一种选择是解密 Django 上的值并将其直接发送到 FastAPI,但我不希望这样做。
如何解密 FastAPI 上的值?