python 實(shí)現(xiàn)aes256加密
基礎(chǔ)知識(shí)
# 在Linux操作系統(tǒng)下,Python3的默認(rèn)環(huán)境編碼變?yōu)榱藆tf-8編碼,所以在編寫代碼的時(shí)候,字符串大部分都是以u(píng)tf-8處理
UTF-8:
1byte = 8bit
1個(gè)英文字符 = 1byte
1個(gè)中文字符 = 3byte
128bit = 16byte = 16個(gè)英文字符
192bit = 24byte = 24個(gè)英文字符
256bit = 32byte = 32個(gè)英文字符
AES256概念
AES是一種對(duì)稱加密算法,對(duì)稱指加密和解密使用同一個(gè)密鑰; 256指密鑰的長度是256bit,即32個(gè)英文字符的長度;密鑰的長度決定了AES加密的輪數(shù)
AES256加密參數(shù)
- 密鑰: 一個(gè)32byte的字符串, 常被叫為key
- 明文: 待加密的字符串;字節(jié)長度(按byte計(jì)算)必須是16的整數(shù)倍,因此,明文加密之前需要被填充
- 模式: 加密模式,常用的有ECB、CBC;具體含義見參考鏈接
- iv 偏移量: CBC模式下需要是16byte字符串; ECB下不需要
參考代碼
# -------------------------------
# -*- coding: utf-8 -*-
# @Author:jianghan
# @Time:2020/11/25 14:46
# @File: crypt.py
# Python版本:3.6.8
# -------------------------------
"""
1、 填充字符串和明文字符串最后一位不能相同
2、 字符串編碼默認(rèn)是utf-8, key和iv默認(rèn)為英文字符;字符串不支持其他編碼或key/iv不支持為中文字符
"""
from enum import Enum, unique
from Crypto.Cipher import AES
@unique
class Mode(Enum):
CBC = AES.MODE_CBC
ECB = AES.MODE_ECB
@unique
class Padding(Enum):
""" 定義填充的字符串 """
SPACE = ' ' # 空格
class AES256Crypto:
def __init__(self, key, mode=Mode.ECB, padding=Padding.SPACE, iv=None):
"""
:param key: 密鑰, 32byte 長度字符串
:param mode: 加密模式, 來源 class Mode
:param iv: 16byte 長度字符串
:param padding: 填充的字符串, 來源class Padding
"""
self.padding = self.check_padding(padding)
self.key = self.padding_key(key)
self.iv = self.padding_iv(iv) if iv else None
self.mode = self.check_mode(mode)
def check_mode(self, mode):
""" 核對(duì) mode """
if mode not in Mode.__members__.values():
raise Exception(f'mode {mode} not allowed!')
if mode == Mode.CBC and not self.iv:
raise Exception(f'iv is required')
return mode
def check_padding(self, padding):
""" 核對(duì) padding """
if padding not in Padding.__members__.values():
raise Exception(f'mode {padding} not allowed!')
return padding
def padding_ret_byte(self, text, _len=16):
""" 填充并轉(zhuǎn)成 bytes """
text = text.encode()
remainder = len(text) % _len
remainder = _len if remainder == 0 else remainder
text += (_len - remainder) * self.padding.value.encode()
return text
def padding_iv(self, iv: str):
""" 補(bǔ)全iv 并轉(zhuǎn)成 bytes"""
if len(iv.encode()) > 16:
raise Exception(f'iv {iv} must <= 16bytes')
return self.padding_ret_byte(iv)
def padding_key(self, key: str):
""" 補(bǔ)全key 并轉(zhuǎn)成 bytes """
if len(key.encode()) > 32:
raise Exception(f'key {key} must <= 32bytes')
return self.padding_ret_byte(key, _len=32)
def encrypt(self, text, encode=None):
"""
加密
:param text: 待加密字符串
:param encode: 傳入base64里面的方法
:return: 若encode=None則不進(jìn)行base加密處理,返回bytes類型數(shù)據(jù)
"""
text = self.padding_ret_byte(text)
# 注意:加密中的和解密中的AES.new()不能使用同一個(gè)對(duì)象,所以在兩處都使用了AES.new()
text = AES.new(key=self.key, mode=self.mode.value, iv=self.iv).encrypt(text)
if encode:
return encode(text).decode()
return text
def decrypt(self, text, decode=None):
""" 解密 """
if decode:
if type(text) == str:
text = text.encode()
text = decode(bytes(text))
else:
if type(text) != bytes:
raise Exception(text)
text = AES.new(key=self.key, mode=self.mode.value, iv=self.iv).decrypt(text)
text = text.strip(self.padding.value.encode())
return text.decode()
使用范例
import json
# 這是一段待加密的字符串
text = '{"upi": "1341343", "overdue": "2020-11-26 00:00:00"}'
key = 't6LtKa3tD5X6qaJ6qOrAW3XmobFrY6ob'
iv = 'NjtP47eSECuOm3s6'
aes = AES256Crypto(key, Mode.CBC, Padding.SPACE, iv)
text_1 = aes.encrypt(text)
# b'\xe7\x1d\xeae\xff\xc7\xc2\xd7\x8c\xf6\xe7\x82u\x7f\x168\xbc\x90\xad\x1e\x85M\xcb\xb0\xb4Ho\x1b\xe4\xec\x9d\x1d\xf93\xeb\x9b\xe7\xa3\xdd$\x8cEa\xab\xf7K~\x91H\xc3]5\xc4\x1a\xd4w[\x83\xb2"FC\x9f\x9d'
text_2 = aes.decrypt(text_1)
# '{"upi": "1341343", "overdue": "2020-11-26 00:00:00"}'
import base64
text_3 = aes.encrypt(text, encode=base64.b16encode)
# 'E71DEA65FFC7C2D78CF6E782757F1638BC90AD1E854DCBB0B4486F1BE4EC9D1DF933EB9BE7A3DD248C4561ABF74B7E9148C35D35C41AD4775B83B22246439F9D'
text_4 = aes.decrypt(text_3, decode=base64.b16decode)
# '{"upi": "1341343", "overdue": "2020-11-26 00:00:00"}'
以上就是python 實(shí)現(xiàn)aes256加密的詳細(xì)內(nèi)容,更多關(guān)于python aes256加密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
django restframework serializer 增加自定義字段操作
這篇文章主要介紹了django restframework serializer 增加自定義字段操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
關(guān)于Python中Flask全局異常處理流程詳解
Flask是一個(gè)基于Python的Web框架,它提供了全局異常處理的機(jī)制來捕獲和處理應(yīng)用程序中的異常,本文將詳細(xì)介紹Flask的全局異常處理,并提供相應(yīng)的代碼示例,需要的朋友可以參考下2023-06-06
詳解Python常用標(biāo)準(zhǔn)庫之os模塊與shutil模塊
os系統(tǒng)模塊與shutil文件操作模塊是Python常用的標(biāo)準(zhǔn)庫,本文將通過示例詳細(xì)講解一下二者的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-06-06
Python如何獲取HTTP請(qǐng)求的Response Body
這篇文章主要介紹了在Python中如何獲取HTTP請(qǐng)求的響應(yīng)體,包括使用內(nèi)置的urllib庫、第三方庫requests以及一些高級(jí)用法,有需要的小伙伴可以了解下2024-11-11
日常整理python執(zhí)行系統(tǒng)命令的常見方法(全)
本文是小編日常整理的些關(guān)于python執(zhí)行系統(tǒng)命令常見的方法,比較全面,特此通過腳本之家這個(gè)平臺(tái)把此篇文章分享給大家供大家參考2015-10-10
四種Python機(jī)器學(xué)習(xí)超參數(shù)搜索方法總結(jié)
在建模時(shí)模型的超參數(shù)對(duì)精度有一定的影響,而設(shè)置和調(diào)整超參數(shù)的取值,往往稱為調(diào)參。本文將演示在sklearn中支持的四種基礎(chǔ)超參數(shù)搜索方法,需要的可以參考一下2022-11-11
Scrapy之爬取結(jié)果導(dǎo)出為Excel的實(shí)現(xiàn)過程
這篇文章主要介紹了Scrapy之爬取結(jié)果導(dǎo)出為Excel的實(shí)現(xiàn)過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
selenium+python自動(dòng)化測試之多窗口切換
這篇文章主要介紹了selenium+python自動(dòng)化測試之多窗口切換,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01

