python实现AES加密和解密


Posted in Python onMarch 27, 2019

一、前言

AES,高级加密标准(英语:Advanced Encryption Standard)。是用来替代DES,目前比较流行的加密算法。
它是一种对称加密算法,与上一篇博文提到过的RSA非对称算法不同,AES只有一个密钥,这个密钥既用来加密,也用于解密。

AES只是个基本算法,实现AES有几种模式,主要有ECB、CBC、CFB和OFB这几种(其实还有个CTR):

1.ECB模式(电子密码本模式:Electronic codebook)

ECB是最简单的块密码加密模式,加密前根据加密块大小(如AES为128位)分成若干块,之后将每块使用相同的密钥单独加密,解密同理。

2.CBC模式(密码分组链接:Cipher-block chaining)

CBC模式对于每个待加密的密码块在加密前会先与前一个密码块的密文异或然后再用加密器加密。第一个明文块与一个叫初始化向量的数据块异或。

3.CFB模式(密文反馈:Cipher feedback)

与ECB和CBC模式只能够加密块数据不同,CFB能够将块密文(Block Cipher)转换为流密文(Stream Cipher)。

4.OFB模式(输出反馈:Output feedback)

OFB是先用块加密器生成密钥流(Keystream),然后再将密钥流与明文流异或得到密文流,解密是先用块加密器生成密钥流,再将密钥流与密文流异或得到明文,由于异或操作的对称性所以加密和解密的流程是完全一样的。

二、代码实现与解析

照旧先上代码:

from Crypto.Cipher import AES
import base64

class AEScoder():
  def __init__(self):
    self.__encryptKey = "iEpSxImA0vpMUAabsjJWug=="
    self.__key = base64.b64decode(self.__encryptKey)
  # AES加密
  def encrypt(self,data):
    BS = 16
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
    cipher = AES.new(self.__key, AES.MODE_ECB)
    encrData = cipher.encrypt(pad(data))
    #encrData = base64.b64encode(encrData)
    return encrData
  # AES解密
  def decrypt(self,encrData):
    #encrData = base64.b64decode(encrData)
    #unpad = lambda s: s[0:-s[len(s)-1]]
    unpad = lambda s: s[0:-s[-1]]
    cipher = AES.new(self.__key, AES.MODE_ECB)
    decrData = unpad(cipher.decrypt(encrData))
    return decrData.decode('utf-8')

简析1:这里采用了面向对象的写法,创建了一个类,同时也偷懒直接把密钥写死成了类的属性。如果有灵活修改密钥的需求,将密钥作为参数传进去即可。

简析2:例子里用了ECB模式,这是AES加密最简单也是很常用的模式。另外一个常用模式是CBC,会比ECB模式多一个初始偏移向量iv:cipher = AES.new(self.__key, AES.MODE_CBC, iv)。

简析3:pad和unpad分别是填充函数和逆填充函数。因为AES加密对加密文本有长度要求,必须是密钥字节数的倍数。这里的encryptKey在经过base64解码后的长度是16个字节。

简析3拓展:实际上AES加密有AES-128、AES-192、AES-256三种,分别对应三种密钥长度128bits(16字节)、192bits(24字节)、256bits(32字节)。当然,密钥越长,安全性越高,加解密花费时间也越长。默认的是AES-128,其安全性完全够用。

填充算法拓展

这里采用的填充算法其实有个专有名词,叫pkcs7padding。

简单解释就是缺几位就补几:填充字符串由一个字节序列组成,每个字节填充该填充字节序列的长度。

如果要填充8个字节,那么填充的字节的值就是0x08;要填充7个字节,那么填入的值就是0x07;以此类推。

如果文本长度正好是BlockSize长度的倍数,也会填充一个BlockSize长度的值。这样的好处是,根据最后一个Byte的填充值即可知道填充字节数。

实际上,java中实现AES加密算法的默认模式是Cipher.getInstance("AES/ECB/PKCS5Padding")
PKCS#5在填充方面,是PKCS#7的一个子集:PKCS#5只是对于8字节(BlockSize=8)进行填充,填充内容为0x01-0x08;但是PKCS#7不仅仅是对8字节填充,其BlockSize范围是1-255字节。
然而因为AES并没有64位(8字节)的块, 如果采用PKCS5, 那么实质上就是采用PKCS7。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python通过apply使用元祖和列表调用函数实例
May 26 Python
Python实现简单的HttpServer服务器示例
Sep 25 Python
Python实现替换文件中指定内容的方法
Mar 19 Python
解决Python3中的中文字符编码的问题
Jul 18 Python
简单了解Python matplotlib线的属性
Jun 29 Python
Python实现Selenium自动化Page模式
Jul 14 Python
让你的Python代码实现类型提示功能
Nov 19 Python
python3连接mysql获取ansible动态inventory脚本
Jan 19 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
Mar 09 Python
django ORM之values和annotate使用详解
May 19 Python
Python大批量搜索引擎图像爬虫工具详解
Nov 16 Python
Python使用UDP实现720p视频传输的操作
Apr 24 Python
详解Python计算机视觉 图像扭曲(仿射扭曲)
Mar 27 #Python
python实现向微信用户发送每日一句 python实现微信聊天机器人
Mar 27 #Python
Pandas读写CSV文件的方法示例
Mar 27 #Python
使用Python的SymPy库解决数学运算问题的方法
Mar 27 #Python
超简单使用Python换脸实例
Mar 27 #Python
python爬虫爬取微博评论案例详解
Mar 27 #Python
Python实现查找字符串数组最长公共前缀示例
Mar 27 #Python
You might like
php 提速工具eAccelerator 配置参数详解
2010/05/16 PHP
非常实用的PHP常用函数汇总
2014/12/17 PHP
JavaScript下利用fso判断文件是否存在的代码
2010/12/11 Javascript
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
2011/05/24 Javascript
jquery 图片缩放拖动的简单实例
2014/01/08 Javascript
JavaScript组件焦点与页内锚点间传值的方法
2015/02/02 Javascript
基于jquery实现在线选座订座之影院篇
2015/08/24 Javascript
Json解析的方法小结
2016/06/22 Javascript
jQuery动态修改字体大小的方法【测试可用】
2016/09/09 Javascript
vue-router路由参数刷新消失的问题解决方法
2017/06/17 Javascript
js中document.write和document.writeln的区别
2018/03/11 Javascript
vue 中 beforeRouteEnter 死循环的问题
2019/04/23 Javascript
详解vue+axios给开发环境和生产环境配置不同的接口地址
2019/08/16 Javascript
vue用BMap百度地图实现即时搜索功能
2019/09/26 Javascript
jQuery实现可以扩展的日历
2020/12/01 jQuery
通过实例解析js可枚举属性与不可枚举属性
2020/12/02 Javascript
[44:15]DOTA2上海特级锦标赛主赛事日 - 5 败者组决赛Liquid VS EG第二局
2016/03/06 DOTA
用Python的urllib库提交WEB表单
2009/02/24 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
在cmd中查看python的安装路径方法
2019/07/03 Python
python 同时读取多个文件的例子
2019/07/16 Python
python实现切割url得到域名、协议、主机名等各个字段的例子
2019/07/25 Python
python3中rank函数的用法
2019/11/27 Python
python应用Axes3D绘图(批量梯度下降算法)
2020/03/25 Python
Python使用文件操作实现一个XX信息管理系统的示例
2020/07/02 Python
python进度条显示-tqmd模块的实现示例
2020/08/23 Python
韩国邮政旗下生鲜食品网上超市:epost
2016/08/27 全球购物
洲际酒店集团美国官网:IHG美国
2017/11/16 全球购物
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
建筑毕业生自我鉴定
2013/10/18 职场文书
机电一体化专业推荐信
2013/12/03 职场文书
大学生第一学年自我鉴定2015
2014/09/28 职场文书
结婚典礼主持词
2015/06/29 职场文书
消防安全主题班会
2015/08/12 职场文书
小学教师教育随笔
2015/08/14 职场文书