django model字段加解密方法

本文介绍了一个使用Python实现的AES加密解密实例,通过定义一个名为Crypto的类来完成加密和解密操作。该类利用PyCryptodome库中的AES算法进行数据处理,并采用ECB模式及PKCS7填充方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# -*- coding=utf-8-*-
# 需要先安装pip3 install pycryptodome
import base64

from decimal import Decimal
import datetime

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes



def force_str(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Similar to smart_str(), except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    # Handle the common case first for performance reasons.
    if issubclass(type(s), str):
        return s
    if strings_only and is_protected_type(s):
        return s
    try:
        if isinstance(s, bytes):
            s = str(s, encoding, errors)
        else:
            s = str(s)
    except UnicodeDecodeError as e:
        print("error: ",e)
    return s


def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
    return force_str(s, encoding, strings_only, errors)


_PROTECTED_TYPES = (
    type(None), int, float, Decimal, datetime.datetime, datetime.date, datetime.time,
)

def is_protected_type(obj):
    """Determine if the object instance is of a protected type.

    Objects of protected types are preserved as-is when passed to
    force_str(strings_only=True).
    """
    return isinstance(obj, _PROTECTED_TYPES)

def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Similar to smart_bytes, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    # Handle the common case first for performance reasons.
    if isinstance(s, bytes):
        if encoding == 'utf-8':
            return s
        else:
            return s.decode('utf-8', errors).encode(encoding, errors)
    if strings_only and is_protected_type(s):
        return s
    if isinstance(s, memoryview):
        return bytes(s)
    return str(s).encode(encoding, errors)

class Crypto:

    def __init__(self, key=None):
        assert len(key) >= 32, "mirage key length must more than 32!"
        self.key = base64.urlsafe_b64encode(force_bytes(key))[:32]

    def encrypt(self, text):
        if text is None:
            return None
        try:
            self.try_decrypt(text)
            return text
        except Exception:
            return self.try_encrypt(text)

    def try_encrypt(self, text):
        encryptor = Cipher(algorithms.AES(self.key), modes.ECB(), default_backend()).encryptor()
        padder = padding.PKCS7(algorithms.AES(self.key).block_size).padder()
        padded_data = padder.update(force_bytes(text)) + padder.finalize()
        encrypted_text = encryptor.update(padded_data) + encryptor.finalize()
        return force_text(base64.urlsafe_b64encode(encrypted_text))

    def try_decrypt(self, encrypted_text):
        decryptor = Cipher(algorithms.AES(self.key), modes.ECB(), default_backend()).decryptor()
        padder = padding.PKCS7(algorithms.AES(self.key).block_size).unpadder()
        decrypted_text = decryptor.update(base64.urlsafe_b64decode(encrypted_text))
        unpadded_text = padder.update(decrypted_text) + padder.finalize()
        return force_text(unpadded_text)

    def decrypt(self, encrypted_text):
        if encrypted_text is None:
            return None
        try:
            return self.try_decrypt(encrypted_text)
        except Exception:
            return encrypted_text

# 加解密
if __name__ == '__main__':
    value='5s29Lry60loQ5vEHe8Xw'
    crypto = Crypto(f'hfusaf2m4ot#7)fkw#di2bu6(cv0@opwmafx8n#6=3d%x^hpl9')  # 初始化密钥
    if value is not None:
        encrypted_text = crypto.encrypt(value)
        print("加密后的字符串:",encrypted_text)
        decrypted_text = crypto.decrypt(encrypted_text)
        print("解密密后的字符串:",decrypted_text)

      

采用的是:AES/CBC/pkcs7padding 的方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值