一、前言
AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。在日常的开发中,无论是实现前后端的接口数据加密,还是数据传输安全性,都使用了AES加密,本文章将从python的角度去实现AES的加密和解密
二、环境安装
AES的加密方式有很多种,例如ECB、CBC、CTR、OFB、CFB,最常用的是ECB和CBC,本文章侧重从CBC模式来实现加密和解密:
#AES加密环境
import base64
from Crypto.Cipher import AES
这是需要用到的库,如果报错的情况下
#AES加密环境
#先卸载这些包,防止一些环境问题
pip uninstall crypto
pip uninstall pycryptodome
#在安装
pip install pycryptodome
三、加密
在加密的过程中,我们会经常碰到一个问题,当一串JSON里面有中文又有英文的时候,我们做加密的时候经常会报这样的错
ValueError: Data must be padded to 16 byte boundary in CBC mode
这里面就牵扯到中文和文字符的长度问题,在utf-8编码:一个中文包含繁体字等于三个字节,一个英文字符等于一个字节。gbk编码:一个中文包含繁体字等于二个字节,一个英文字符等于一个字节,不多说,直接上代码
iv='shzxsjicommunity' #偏移量
key='shzxsjicommunity' #密钥
#补足字节方法
def pad(value):
BLOCK_SIZE = 16 # 设定字节长度
count=len(value)
if(count%BLOCK_SIZE !=0):
add=BLOCK_SIZE-(count%BLOCK_SIZE)
else:
add=0
text=value+("\0".encode()*add) # 这里的"\0"必须编码成bytes,不然无法和text拼接
return text
# 将明文用AES加密
def AES_en(data):
# 将长度不足16字节的字符串补齐
data=pad(data.encode())#注意在这个地方要把传过来的数据编码成bytes,不然还是会报上面说的那个错
# 创建加密对象
AES_obj = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
# 完成加密
AES_en_str = AES_obj.encrypt(data)
# 用base64编码一下
AES_en_str = base64.b64encode(AES_en_str)
# 最后将密文转化成字符串
AES_en_str = AES_en_str.decode("utf-8")
return AES_en_str
data="{'test':'我是一个小小的程序员!'}" #测试数据
b=AES_en(data1)
print(f"加密为:{b}") #此写法python3.6以上才支持
输出结果
加密为:6kJuZxX6EUUp9QgeBbDUuHiQznKMQz87GaQxKaVPlVIhwODIKCBcdz70ZhB9PFbp
四、解密
直接上代码
输出结果
def AES_de(data):
# 解密过程逆着加密过程写
# 将密文字符串重新编码成二进制形式
data = data.encode("utf-8")
# 将base64的编码解开
data = base64.decodebytes(data)
# 创建解密对象
AES_de_obj = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
# 完成解密
AES_de_str = AES_de_obj.decrypt(data)
# 去掉补上的空格
AES_de_str =AES_de_str.strip()
# 对明文解码
AES_de_str = AES_de_str.decode("utf-8")
return AES_de_str.strip(b'\x00'.decode()) #去除特定的空格
我们把加密上面的结果放到解密来,输出结果
data='6kJuZxX6EUUp9QgeBbDUuHiQznKMQz87GaQxKaVPlVIhwODIKCBcdz70ZhB9PFbp'
a=AES_de(data)
print(f"解密为:{a}")
输出结果文章来源:https://www.toymoban.com/news/detail-519599.html
解密为:{'name':'我是一个小小的程序员!'}
五、完整代码
# -*- coding: utf-8 -*-
#AES加密
import base64
from Crypto.Cipher import AES
iv='shzxsjicommunity'#偏移量
key='shzxsjicommunity'#密钥
#补足字节方法
def pad(value):
BLOCK_SIZE = 16 # 设定字节长度
count=len(value)
if(count%BLOCK_SIZE !=0):
add=BLOCK_SIZE-(count%BLOCK_SIZE)
else:
add=0
text=value+("\0".encode()*add) # 这里的"\0"必须编码成bytes,不然无法和text拼接
return text
# 将明文用AES加密
def AES_en(data):
# 将长度不足16字节的字符串补齐
data=pad(data.encode())
# 创建加密对象
AES_obj = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
# 完成加密
AES_en_str = AES_obj.encrypt(data)
# 用base64编码一下
AES_en_str = base64.b64encode(AES_en_str)
# 最后将密文转化成字符串
AES_en_str = AES_en_str.decode("utf-8")
return AES_en_str
def AES_de(data):
# 解密过程逆着加密过程写
# 将密文字符串重新编码成二进制形式
data = data.encode("utf-8")
# 将base64的编码解开
data = base64.decodebytes(data)
# 创建解密对象
AES_de_obj = AES.new(key.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
# 完成解密
AES_de_str = AES_de_obj.decrypt(data)
# 去掉补上的空格
AES_de_str =AES_de_str.strip()
# 对明文解码
AES_de_str = AES_de_str.decode("utf-8")
return AES_de_str.strip(b'\x00'.decode())
if __name__=='__main__':
data="{'test':'我是一个小小的程序员!'}"
b=AES_en(data)
print(f"加密为:{b}")#python3.6以上的写法
a=AES_de(b)
print(f"解密为:{a}")
我们可以通过该网站看自己的加密和解密是否正确:验证.
希望与大家一起学习交流!!!有什么python和go的问题可以私信我文章来源地址https://www.toymoban.com/news/detail-519599.html
到了这里,关于PYTHON实现AES加密,中英文通用!!!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!