Django Fernet Fields 字段加密实战:安装、配置与安全限制

Ryan
Ryan
发布时间:2026-10-13 | 6人浏览过
原创

本文详解 Django 插件 django-fernet-fields 的安装与核心用法。通过 EncryptedCharField 等字段实现应用层对称加密,确保密钥不入库。重点说明非确定性加密导致的索引、唯一性约束及查找限制,并提供可空字段的安全处理建议,保障数据库存储安全。

Fernet 库概述

一、Fernet 库概述

Fernet 是 Django 模型字段中用于对称加密的工具,底层依赖 cryptography 库实现。

官方帮助文档

1、环境要求

django-fernet-fields 兼容 Django 1.8.2 及以上版本,支持 Python 2.7、3.3、3.4,以及 PyPy 和 PyPy3 环境。

经测试,该库在 PostgreSQL、SQLite 和 MySQL 数据库中均可正常运行。理论上,任何支持 BinaryField 的 Django 数据库后端均能兼容此功能。

2、安装步骤

django-fernet-fields 已发布至 PyPI,可通过以下命令进行安装:


pip install django-fernet-fields

Fernet 具体应用

二、Fernet 具体应用

1、基础用法示例

只需在模型中导入并使用对应的字段类即可:


from django.db import models
from rbac.models import *
from fernet_fields import EncryptedCharField
class Customer(models.Model):
  """ 客户(学生)表 """
  name = EncryptedCharField(verbose_name='姓名', max_length=64)
  gender_choices = (
    (1, '男'),
    (2, '女')
  )

定义变量后,读取 name 字段的值与常规操作无异。但在数据写入数据库前,系统会自动执行加密;从数据库读取时,则自动解密。

整个加密和解密过程均在应用程序本地完成,密钥永远不会传输至数据库服务器。数据库仅存储该字段的加密后密文。

2、支持的字段类型

常用字段类包括:EncryptedCharField、EncryptedEmailField、EncryptedIntegerField、EncryptedDateField 以及 EncryptedDateTimeField。所有字段类均接受与非加密版本相同的参数。

若需创建其他自定义字段的加密版本,可继承 EncryptedField 及其他基础字段类:


from fernet_fields import EncryptedField
from somewhere import MyField
class MyEncryptedField(EncryptedField, MyField):
  pass

3、处理可空字段

支持使用可空的加密字段;Python 中的 None 值会被转换为数据库列中的实际 NULL。需注意,这通常会向攻击者暴露数据是否存在。若存在此安全隐患,请避免使用可空加密字段;建议改为非可空加密字段,并存储一个作为标记的“空”值(该值将像其他值一样被加密)。

索引、约束与查询限制

三、索引、约束与查询限制

由于 Fernet 加密是非确定性的(即使使用相同密钥,相同明文每次加密生成的令牌也不同),因此对加密数据建立索引、强制执行唯一性约束或执行查找操作均无意义。每个加密值始终不同,完全匹配查找必然失败;其他查找结果也将失去意义。

基于上述原因,若对 EncryptedField 设置 db_index=True、unique=True 或 primary_key=True,将抛出 django.core.exceptions.ImproperlyConfigured 异常。此外,对 EncryptedField 执行除空值检查外的任何类型查找,均会抛出 django.core.exceptions.FieldError。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表