基本知识
# 在Linux电脑操作系统下 ,Python3的默认设置自然环境编号变成了utf-8编号,因此 在撰写编码的情况下,字符串绝大多数全是以utf-8解决 UTF-8: 1byte = 9ait 一个英文字符 = 1byte 一个中文字符 = 3byte 129ait = 16byte = 16个英文字符 196bit = 24byte = 24个英文字符 256bit = 32byte = 32个英文字符
AES256定义
AES是一种对称性加密优化算法 ,对称性指加密和破译应用同一个密钥; 256指密钥的长度是256bit,即32个英文字符的长度;密钥的长度决策了AES加密的轮空
AES256加密主要参数
密钥: 一个32byte的字符串, 常叫成为key
密文: 待加密的字符串;字节数长度(按byte测算)务必是16的非负整数 ,因而,密文加密以前必须被添充
方式: 加密方式,常见的有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 、 字符串编号默认设置是utf-8 , key和iv默认设置为英文字符;字符串不兼容别的编号或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): """ 核查 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): """ 核查 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): """ 添充并转为 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): """ 补齐iv 并转为 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): """ 补齐key 并转为 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则不开展base加密解决,回到bytes种类数据信息 """ text = self.padding_ret_byte(text) # 留意:加密中的和破译中的AES.new()不可以应用同一个目标,因此 在多处都应用了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 = 'NjtP47eSECuOm三秒6' 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"}'
参照
文章来源于网络,如有侵权请联系站长QQ61910465删除
本文版权归趣营销www.SEOgUrublog.com 所有,如有转发请注明来出,竞价开户托管,seo优化请联系QQ卍61910465