Django Fernet Fields 字段加密实战:安装、配置与安全限制
本文详解 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。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













