Django数据加密字段默认有了吗

wen python案例 2

本文目录导读:

Django数据加密字段默认有了吗

  1. 如果你需要加密存储,目前主流的做法是使用第三方库
  2. 重要提醒

Django 默认的模型字段 中,没有 内置一个可以直接使用的“数据加密字段”(EncryptedCharField)。

Django 标准字段(如 CharFieldTextField)存储的是明文数据。


如果你需要加密存储,目前主流的做法是使用第三方库

最常用、最成熟的库是 django-cryptographydjango-encrypted-model-fields

使用 django-cryptography(推荐,最简单)

安装:

pip install django-cryptography

使用示例(在 models.py 中):

from django.db import models
from django_cryptography.fields import encrypt
class User(models.Model):
    name = models.CharField(max_length=100)
    # 这个字段会被自动加密/解密
    credit_card = encrypt(models.CharField(max_length=16))

特点

  • 你像使用普通字段一样赋值和读取
  • Django 会自动在数据库层面加密存储,读取时自动解密
  • 底层使用 AES 加密
  • 缺点:加密密钥写在 Django 的 SECRET_KEY 中,如果你改了 SECRET_KEY,之前加密的数据就无法解密

使用 django-encrypted-model-fields

安装:

pip install django-encrypted-model-fields

设置密钥(settings.py):

FIELD_ENCRYPTION_KEY = '你的32位base64编码密钥'

使用示例:

from django.db import models
from encrypted_model_fields.fields import EncryptedCharField
class User(models.Model):
    ssn = EncryptedCharField(max_length=32)

手动实现(如果不想用第三方库)

你可以自己重写 __getattr__ 或使用 Django 的 Field 子类,结合 pycryptodome 等库手动加解密。

示例(简化版):

from django.db import models
from cryptography.fernet import Fernet
from django.conf import settings
key = settings.SECRET_KEY[:32]  # 注意:实际不应该直接用SECRET_KEY
cipher = Fernet(key)
class EncryptedField(models.CharField):
    def get_prep_value(self, value):
        value = super().get_prep_value(value)
        return cipher.encrypt(value.encode()).decode()
    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return cipher.decrypt(value.encode()).decode()

重要提醒

  1. 密钥管理是关键
    无论用什么方案,加密密钥不能丢失,如果密钥丢失,所有加密数据将永久不可读取。

  2. 性能影响
    加密/解密需要 CPU 计算,对于高并发查询场景,如果频繁对加密字段进行 filterorder_bydistinct,数据库无法利用索引(因为存储的是密文),性能会急剧下降。

  3. 搜索问题
    加密字段无法直接做模糊搜索(__contains__icontains)或比较查询,如果一定要搜索,你需要额外维护一个明文索引字段(手机号后4位)。

  4. Django 内置的密码字段
    Django 自带的 PasswordField哈希(不可逆),不是加密(可逆),两者目的不同,密码用哈希,敏感数据用加密。


场景 推荐做法
密码存储 Django 自带的 PasswordField(哈希)
需要可逆加密(如身份证、信用卡) 使用 django-cryptographydjango-encrypted-model-fields
高性能/可搜索 考虑用数据库自带的加密函数(如 MySQL AES_ENCRYPT)或应用层加密+额外索引

所以结论是:Django 没有内建加密字段,但第三方库 django-cryptography 是最接近“开箱即用”的解决方案。

抱歉,评论功能暂时关闭!