You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中对整数字段实现加密/令牌化处理保障数据安全

Django 保密整数字段实现方案

你示例中Django原生密码字段的核心逻辑是不可逆哈希:使用set_password时自动对明文做哈希处理后存储,authenticate时将输入值做相同哈希后和存储值比对,全程无法从存储的密文还原出原始明文,仅支持匹配校验。

如果你的需求是「仅校验数值是否匹配、不需要给用户展示明文」,可以直接复用Django的密码哈希逻辑,实现和密码字段完全一致的效果;如果需要支持所属用户查看明文,就要改用对称加密方案实现,具体方案如下:


方案1:无需还原明文(和原生密码字段逻辑完全一致)

直接复用Django内置的密码哈希工具即可:

from django.db import models
from django.contrib.auth.hashers import make_password, check_password
from django.contrib.auth.models import User

class UserSecret(models.Model):
    owner = models.OneToOneField(User, on_delete=models.CASCADE)
    # 存储哈希后的整数值,底层用CharField即可
    secret_num_hash = models.CharField(max_length=256)

    # 类似set_password的设值方法
    def set_secret_num(self, raw_num: int):
        self.secret_num_hash = make_password(str(raw_num))

    # 类似authenticate的校验方法
    def check_secret_num(self, input_num: int) -> bool:
        return check_password(str(input_num), self.secret_num_hash)

调用方式和你示例的密码操作完全一致:

# 存值
obj = UserSecret.objects.create(owner=request.user)
obj.set_secret_num(123456)
obj.save()

# 校验
is_match = obj.check_secret_num(123456) # 返回True

该方案下存储的是不可逆哈希值,就算是管理员也无法从密文还原出原始整数值。


方案2:需要支持所属用户查看明文(对称加密实现)

该方案采用对称加密算法,存储时加密为密文,有权限的用户可以解密查看明文:

第一步:定义自定义加密整数字段

from django.db import models
from django.core import signing
from django.core.exceptions import ValidationError

class EncryptedIntegerField(models.Field):
    description = "对称加密存储的整数字段"

    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        try:
            # 自动解密数据库读取的密文
            return signing.loads(value)
        except signing.BadSignature:
            raise ValidationError("加密数据已被篡改")

    def to_python(self, value):
        if isinstance(value, int) or value is None:
            return value
        try:
            return signing.loads(value)
        except signing.BadSignature:
            raise ValidationError("加密数据已被篡改")

    def get_prep_value(self, value):
        if value is None:
            return value
        # 写入数据库前自动加密
        return signing.dumps(value)

    def get_internal_type(self):
        # 加密后为字符串,底层用TextField存储
        return "TextField"

第二步:模型中使用并加权限控制

from django.db import models
from django.contrib.auth.models import User
from .fields import EncryptedIntegerField

class UserSecret(models.Model):
    owner = models.OneToOneField(User, on_delete=models.CASCADE)
    secret_num = EncryptedIntegerField()

    # 仅所属用户可获取明文
    def get_secret_num(self, request_user: User) -> int | None:
        if request_user == self.owner:
            return self.secret_num
        return None

第三步:Admin后台隐藏字段

配置admin.py避免管理员看到加密后的内容:

from django.contrib import admin
from .models import UserSecret

@admin.register(UserSecret)
class UserSecretAdmin(admin.ModelAdmin):
    list_display = ('owner',)
    exclude = ('secret_num',)

注意事项

  • 方案1的不可逆哈希安全性更高,不需要还原明文时优先选择该方案
  • 方案2的加密密钥默认使用Django配置的SECRET_KEY,生产环境务必保证该值不泄露,泄露后所有加密数据可被破解
  • 生产环境建议优先使用django-fernet-fields等成熟第三方加密字段库,避免自行实现的加密逻辑有安全漏洞

内容的提问来源于stack exchange,提问作者Ali Husham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 09:39:03