对称加密(AES)

对称加密(AES)

AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。
常见的对称加密:AES,DES,3DES.我们这里讨论AES。
安装:

pip install pycryptodome

AES加密最常用的模式就是CBC模式和ECB模式,当然还有很多其它模式,他们都属于AES加密。ECB模式和CBC模式俩者区别就是ECB不需要iv偏移量,而CBC需要。

长度
	16:*AES-128*
	24: *AES-192*
	32:*AES-256*

MODE加密模式.
	常见的ECB,CBC
ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。
"""
ECB 以 16:*AES-128* 算法为例:我们有一个要加密的,就会按照16分割,然后分别加密,再把所有的加密的组合起来
"""

image

CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解
难度。
"""
CBC:也是分块,第一块加密之后,第一块加密数据与第二块明文做异或
"""

image

CBC加密流程

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

# (1) 确认 key 和 iv 必须是16位/24位/32位
key = "0123456789123456".encode() 
iv = "qazwsxedcrfvtgby".encode() 
# (2)创建AES对象
aes = AES.new(key, AES.MODE_CBC, iv) # key, 模式, iv

# (3)对数据做加密,数据一定要是16/24/32的倍数
data = "xiaoxiaoxiao".encode()  # 数据不实16的倍数,下面使用pad函数补齐

pad_data = pad(data, 16) # 不是16的倍数,需要补齐,这里有个规律就是缺几位就补几【现在是缺4位补的就是4】
print(pad_data) # b'xiaoxiaoxiao\x04\x04\x04\x04'
encrypt_date = aes.encrypt(pad_data)
print(encrypt_date) # b'\x91\x8f\xcb\xcfM\xa8\xbf\xc2\x87\x8b\x1c\x01Y\xb5\x17X'

# (4)base64编码,原因是encrypt_date会有很多特殊的符号

base64_encrypt_date = base64.b64encode(encrypt_date).decode()
print(base64_encrypt_date) # kY/Lz02ov8KHixwBWbUXWA==

如果加密的是一个字典,在解密的时候就有一个“坑”

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

# (1) 确认 key 和 iv 必须是16位/24位/32位
key = "0123456789123456".encode() 
iv = "qazwsxedcrfvtgby".encode() 
# (2)创建AES对象
aes = AES.new(key, AES.MODE_CBC, iv) # key 模式 iv

# (3)对数据做加密,数据一定要是16/24/32的倍数
# data = "xiaoxiaoxiao".encode()  # 数据不实16的倍数,下面使用pad函数补齐
data = "{'a':1}".encode() 

pad_data = pad(data, 16) # 不是16的倍数,需要补齐,这里有个规律就是缺几位就补几【现在是缺4位补的就是4】
print(pad_data) # b"{'a':1}\t\t\t\t\t\t\t\t\t"
encrypt_date = aes.encrypt(pad_data)
print(encrypt_date) # b"\xaftD7'\x9e\x89(A\x80\x0e$\x19\x98\x80{"

# (4)base64编码,原因是encrypt_date会有很多特殊的符号

base64_encrypt_date = base64.b64encode(encrypt_date).decode()
print(base64_encrypt_date) # r3RENyeeiShBgA4kGZiAew==

解密

以上面的字典的加密为例,来解密

# 此段代码是个半成品
import base64
from Crypto.Cipher import AES

base64_encrypt_date = "r3RENyeeiShBgA4kGZiAew=="

# (1)base64解码
encrypt_date = base64.b64decode(base64_encrypt_date)
print(encrypt_date) # b"\xaftD7'\x9e\x89(A\x80\x0e$\x19\x98\x80{"


# (2)解密
# 2.1 确认好解密的参数
key = "0123456789123456".encode() 
iv = "qazwsxedcrfvtgby".encode() 
# 2.2 创建AES对象
aes = AES.new(key, AES.MODE_CBC, iv) # key 模式 iv

# 2.3 对数据进行解密
data = aes.decrypt(encrypt_date)
print(data) # b"{'a':1}\t\t\t\t\t\t\t\t\t"
此时我们的数据有了\t,,,因为我们在数据加密的是不够位数,就补齐的原因,所有要去掉【见下面代码】

完整版

import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad



base64_encrypt_date = "r3RENyeeiShBgA4kGZiAew=="

# (1)base64解码
encrypt_date = base64.b64decode(base64_encrypt_date)
print(encrypt_date) # b'\x91\x8f\xcb\xcfM\xa8\xbf\xc2\x87\x8b\x1c\x01Y\xb5\x17X'


# (2)解密
# 2.1 确认好解密的参数
key = "0123456789123456".encode() 
iv = "qazwsxedcrfvtgby".encode() 
# 2.2 创建AES对象
aes = AES.new(key, AES.MODE_CBC, iv) # key 模式 iv

# 2.3 对数据进行解密
data = aes.decrypt(encrypt_date)
# 2.4 去掉填充
data = unpad(data, AES.block_size) # AES.block_size 默认就是16
print(data, type(data)) # b"{'a':1}"
# 2.5 将字节转换为字符串
print(data.decode(), type(data.decode()))# {'a':1} <class 'str'>
# 2.6 将字符串转换为字典
print(eval(data.decode()), type(eval(data.decode())))# {'a':1} <class 'dict'>
posted @ 2024-07-16 10:21  流年中渲染了微笑  阅读(1)  评论(0编辑  收藏  举报