Django 字段加密存储并支持检索
本文將介紹一種在 Django 框架內將數據進行加密存儲到數據庫并且支持檢索的方法,此方法采用單向加密和非對稱加密解密技術結合來實現。
概念解釋:
非對稱加密算法需要兩個密鑰來進行加密和解密,這兩個秘鑰是公開密鑰(publickey,簡稱公鑰)和私有密鑰(privatekey,簡稱私鑰)。
單向加密又稱為不可逆加密算法,在加密過程中不使用密鑰,明文由系統加密處理成密文,密文無法解密。一般適合于驗證,在驗證過程中,重新輸入明文,并經過同樣的加密算法處理,得到相同的密文并被系統重新認證。廣泛使用于口令加密。
此文使用的非對稱加密方法每次加密同樣的數據內容會產生不同的密文,因此不能被用于數據驗證,只能用于數據存儲。而單向加密方法不支持將數據進行解密,只能用于數據驗證。因此,通過此兩種方法的功能結合,我們可以將數據進行安全的存儲,同時也支持數據檢索。
相關的依賴
非對稱加密算法依賴于 rsa 包,可以通過 pip 進行安裝。
pip install rsa==4.0模塊代碼
可以創建一個文件,比如 utils.py,也可以將代碼直接放置在項目代碼內。
import base64 import binascii import hashlib import rsafrom django.conf import settingsdef generate_keys():"""生成公鑰和私鑰文件:return:"""public_key, private_key = rsa.newkeys(1024)pub = public_key.save_pkcs1()public_file = open('public.pem', 'wb')public_file.write(pub)public_file.close()pri = private_key.save_pkcs1()private_file = open('private.pem', 'wb')private_file.write(pri)private_file.close()def rsa_encrypt(d_str):"""對文本進行加密:param d_str: 文本:return: 加密后的數據"""p = settings.PUBKEY.encode()public_key = rsa.PublicKey.load_pkcs1(p)# 將字符串進行編碼content = d_str.encode('utf-8')# 公鑰加密crypto = rsa.encrypt(content, public_key)return base64.b64encode(crypto).decode()def rsa_decrypt(crypto):"""對文本進行解密:param crypto: 密文:return: 解密后的數據"""p = settings.PRIVKEY.encode()private_key = rsa.PrivateKey.load_pkcs1(p)# 解密content = rsa.decrypt(base64.b64decode(crypto), private_key)# 解碼content = content.decode('utf-8')return contentdef pbkdf2_hmac_encrypt(d_str):"""單向加密數據:param d_str: 文本:return: 加密后的數據"""dk = hashlib.pbkdf2_hmac('sha256', d_str.encode(), settings.SECRET_KEY.encode(), 100)crypto = binascii.hexlify(dk).decode()return crypto通過運行 python3 manage.py shell 進入調試模式。
from somewhere.utils import * # somewhere 為 utils 文件所存放的路徑,比如你將 utils.py 存放在 app 目錄下面,則應寫為 from app.utils import * generate_keys()密鑰文件 private.pem 和 public.pem 生成以后,將公鑰和私鑰分別復制到項目的 settings.py 里面。
PUBKEY = """ -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAJTRZYr0hOh8yARYD5xfTK6eMtgVmP4fVpFZbRiCWCOgYLqcVUmk6GPU w7638jnD52kLd9BwZoEyxyqDrCWUkZoLNYjaczw5R+YXuDGr4bICPR597PMNfnGd ZeitlrfpEEDMJmzE7jakYiXe9N9Q25VGDqQOpZi0nLUw6ipguMrpAgMBAAE= -----END RSA PUBLIC KEY----- """PRIVKEY = """ -----BEGIN RSA PRIVATE KEY----- MIICYAIBAAKBgQCU0WWK9ITofMgEWA+cX0yunjLYFZj+H1aRWW0YglgjoGC6nFVJ pOhj1MO+t/I5w+dpC3fQcGaBMscqg6wllJGaCzWI2nM8OUfmF7gxq+GyAj0efezz DX5xnWXorZa36RBAzCZsxO42pGIl3vTfUNuVRg6kDqWYtJy1MOoqYLjK6QIDAQAB AoGAGK9vT5Bl54ajSw0scbzhJGn7dxqGCUk7e9rAnPsqEabNxMaf4xpmrgCiA6XR mUFkxmjvk/TBHBdHMEctBkGWX34NKdQGGJYZU4xv5+LlgpV9/VfKsHMCb0nOYCjG MdxFp6ShM7EAGS5I0LJFIUjJAivoxhMjm8BjqipuvbYU0TECRQDjmwGfNuyJLREk TRylsoLOnKedX9wegzeUbeRQl4WXpzbj0Sc5/F9Rd80zFjDejTDrxibFZChovs0r 8/dTtfVNGWu1tQI9AKdiKue+w6cGups7ZU2ZeeUxFkSFkjA+BHViY2tfKQ4lZiSQ xOWLuhdTLQWb+4udrXu3JL4YE3wgNWpA5QJEdk1LOoZBy8sw7b1m9nkipGGofZQl xXZOnUfBNGKNfZXcYe2Ehg83PBEZB0SxgfvBQctsu4yjtE34NrBIDaq2Jazg30EC PDoOP4lvzhbBq7mpyUI4CGJpOyr7FTBsYkmAnbEhKXFBoYLvP4vKgfoTHFuEtaPA RerSJAlW+nMkDMLUzQJFAKi5gYuNvXisZl7R7YKDUHk86b6yuRn/f4ROhB8Mvf0r y/kIGO21GqL04fnTApW7z7VCuiWUGJg0TqlpzO2vyeOy71KM -----END RSA PRIVATE KEY----- """字段加密應用
比如你要將某個敏感字段進行加密存儲到數據庫。
class Company(models.Model):mobile_data = models.TextField(verbose_name=_('手機號-數據'), max_length=2000, null=True, blank=True)mobile_index = models.TextField(verbose_name=_('手機號-索引'), max_length=2000, null=True, blank=True, unique=True)objects = models.Manager()def _get_mobile(self):"""獲取 mobile 的數據進行解密后返回:return: 解密后的數據"""if self.mobile_data:return rsa_decrypt(self.mobile_data)else:return Nonedef _set_mobile(self, mobile):"""設置 mobile 的值:return: 加密后存儲"""self.mobile_data = rsa_encrypt(mobile)self.mobile_index = pbkdf2_hmac_encrypt(mobile)mobile = property(_get_mobile, _set_mobile)class Meta:ordering = ['id']def __str__(self):return self.mobile當你設置 mobile 字段數據時,自動會將 mobile_index 和 mobile_data 進行存儲。
mobile = "110" # 采用 create 方法 Company.objects.create(mobile=mobile) # 你也可以通過 update_or_create 進行創建,此方法還支持將數據進行更新 Company.objects.update_or_create(mobile_index=pbkdf2_hmac_encrypt(mobile), defaults={'mobile':mobile}) # 首先會通過 mobile_index 進行搜索,是否唯一,創建的話也會將 mobile_data 值寫入當你想要進行搜索 mobile 時,你可以用以下方法:
mobile = '110' obj = Company.objects.filter(mobile_index=pbkdf2_hmac_encrypt(mobile))總結
采用此方法你可以將敏感數據加密存儲到數據庫,單向加密方法支持你進行搜索驗證,不對稱加密解密支持將數據進行解密。
總結
以上是生活随笔為你收集整理的Django 字段加密存储并支持检索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ibmmq 通道命令_IBM WebSp
- 下一篇: Nginx 0.8.x + PHP 5.