python 实现aes256加密


Posted in Python onNovember 27, 2020

基础知识

# 在Linux操作系统下,Python3的默认环境编码变为了utf-8编码,所以在编写代码的时候,字符串大部分都是以utf-8处理
UTF-8:
1byte = 8bit
1个英文字符 = 1byte
1个中文字符 = 3byte

128bit = 16byte = 16个英文字符
192bit = 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 = '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 实现aes256加密的详细内容,更多关于python aes256加密的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python安装Numpy和matplotlib的方法(推荐)
Nov 02 Python
Python+matplotlib+numpy实现在不同平面的二维条形图
Jan 02 Python
Python+Django搭建自己的blog网站
Mar 13 Python
python筛选出两个文件中重复行的方法
May 31 Python
利用pandas读取中文数据集的方法
Jul 25 Python
pandas条件组合筛选和按范围筛选的示例代码
Aug 26 Python
python实现滑雪者小游戏
Feb 22 Python
python递归调用中的坑:打印有值, 返回却None
Mar 16 Python
JupyterNotebook 输出窗口的显示效果调整方法
Apr 13 Python
django 模型字段设置默认值代码
Jul 15 Python
Python扫描端口的实现
Jan 25 Python
Python面试不修改数组找出重复的数字
May 20 Python
pandas使用函数批量处理数据(map、apply、applymap)
Nov 27 #Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
Nov 27 #Python
Python基于template实现字符串替换
Nov 27 #Python
使用Python画了一棵圣诞树的实例代码
Nov 27 #Python
python 用opencv实现霍夫线变换
Nov 27 #Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
Nov 27 #Python
五种Python转义表示法
Nov 27 #Python
You might like
使用php+apc实现上传进度条且在IE7下不显示的问题解决方法
2013/04/25 PHP
PHP CURL获取返回值的方法
2014/05/04 PHP
PHP文件操作方法汇总
2015/07/01 PHP
浅谈PHP的exec()函数无返回值排查方法(必看)
2017/03/31 PHP
PHP使用DOM对XML解析处理操作示例
2019/07/04 PHP
PHP调用QQ互联接口实现QQ登录网站功能示例
2019/10/24 PHP
yii2.0框架实现上传excel文件后导入到数据库的方法示例
2020/04/13 PHP
使两个iframe的高度与内容自适应,且相等
2006/11/20 Javascript
JavaScript 空位补零实现代码
2010/02/26 Javascript
javascript trim函数在IE下不能用的解决方法
2014/09/12 Javascript
AngularJS中的模块详解
2015/01/29 Javascript
利用fecha进行JS日期处理
2016/11/21 Javascript
实现一个简单的vue无限加载指令方法
2017/01/10 Javascript
使用nvm管理不同版本的node与npm的方法
2017/10/31 Javascript
vue设置导航栏、侧边栏为公共页面的例子
2019/11/01 Javascript
Vue中fragment.js使用方法小结
2020/02/17 Javascript
js里面的变量范围分享
2020/07/18 Javascript
Kettle中使用JavaScrip调用jar包对文件内容进行MD5加密的操作方法
2020/09/04 Javascript
[01:08:33]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python logging类库使用例子
2014/11/22 Python
从Python的源码来解析Python下的freeblock
2015/05/11 Python
Python 错误和异常代码详解
2018/01/29 Python
Python爬虫实现抓取京东店铺信息及下载图片功能示例
2018/08/07 Python
详解python中TCP协议中的粘包问题
2019/03/22 Python
python每天定时运行某程序代码
2019/08/16 Python
python线程中的同步问题及解决方法
2019/08/29 Python
Python是什么 Python的用处
2020/05/26 Python
Python3爬虫发送请求的知识点实例
2020/07/30 Python
详解CSS3选择器:nth-child和:nth-of-type之间的差异
2017/09/18 HTML / CSS
外贸学院会计专业应届生求职信
2013/11/14 职场文书
加拿大探亲邀请信
2014/01/28 职场文书
学生周末回家住宿长期请假条
2014/02/15 职场文书
食品仓管员岗位职责
2015/04/01 职场文书
Python insert() / append() 用法 Leetcode实战演示
2021/03/31 Python
NodeJs内存占用过高的排查实战记录
2021/05/10 NodeJs
JS前端使用canvas实现物体的点选示例
2022/08/05 Javascript