AES加密解密python实现

1.前言

        关于现代密码学算法,可以查看以下博客全面了解

CISSP考试要求里的“应用密码学”内容辅助记忆趣味串讲_晓翔仔的博客-CSDN博客

        AES的细节知识,可以查阅

AES加密算法的详细介绍与实现_TimeShatter的博客-CSDN博客

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

AES加解密算法的参数
参数作用及数据类型
秘钥加密的时候用秘钥,解密的时候需要同样的秘钥才能解出来; 数据类型为bytes
明文需要加密的参数; 数据类型为bytes
模式 aes 加密常用的有 ECB 和 CBC 模式(这两个模式最常见,还有其他模式);数据类型为aes类内部的枚举量
iv 偏移量这个参数在 ECB 模式下不需要,在 CBC 模式下需要;数据类型为bytes


 

2. ECB模式 

针对ECB模式的加密解密,参数中有几个限制:

  1. 秘钥必须为16字节或者16字节的倍数的字节型数据。
  2. 明文必须为16字节或者16字节的倍数的字节型数据,如果不够16字节需要进行补全

2.1 短字符串加解密

如果需要加解密的是很短的额字符串,直接使用以下代码

from Crypto.Cipher import AES

password = b'1234567812345678' #秘钥,b就是表示为bytes类型
text = b'abcdefghijklmnhi' #需要加密的内容,bytes类型
aes = AES.new(password,AES.MODE_ECB) #创建一个aes对象
# AES.MODE_ECB 表示模式是ECB模式
en_text = aes.encrypt(text) #加密明文
print("密文:",en_text) #加密明文,bytes类型
den_text = aes.decrypt(en_text) # 解密密文
print("明文:",den_text)

自测输出

密文: b'WU\xe0\x0e\xa3\x87\x12\x95\\]O\xd7\xe3\xd4 )'
明文: b'abcdefghijklmnhi'

Process finished with exit code 0

如果是BASE64编码的密文需要解密呢?

使用如下代码

from Crypto.Cipher import AES
import base64

password = b'1234567812345678'
aes = AES.new(password,AES.MODE_ECB)
# en_text = b"Pd04a4bt7Bcf97KEfgLGQw=="
en_text = "Pd04a4bt7Bcf97KEfgLGQw==".encode() #将字符串转换成bytes数据
en_text = base64.decodebytes(en_text) #将进行base64解码,返回值依然是bytes
den_text = aes.decrypt(en_text)
print("明文:",den_text.decode("gbk"))

因为无论是 utf8 和 gbk 编码,针对英文字符编码都是一个字符对应一个字节,所以这里**encode()**函数主要作用就是转换成bytes数据,然后使用base64进行解码。

自测输出

明文: 好好学习天天向上

Process finished with exit code 0

        有一些AES加密,所用的秘钥,或者IV向量是通过 base64编码或者 hexstr编码后的。针对这种,首先要进行的就是进行解码,都转换回 bytes数据,再次强调,python实现 AES加密解密传递的参数都是 bytes(字节型) 数据。

        hexstr,base64编码解码例子:

import base64
import binascii
data = "hello".encode()
data = base64.b64encode(data)
print("base64编码:",data)
data = base64.b64decode(data)
print("base64解码:",data)
data = binascii.b2a_hex(data)
print("hexstr编码:",data)
data = binascii.a2b_hex(data)
print("hexstr解码:",data)

自测输出:

base64编码: b'aGVsbG8='
base64解码: b'hello'
hexstr编码: b'68656c6c6f'
hexstr解码: b'hello'

Process finished with exit code 0

2.2 对二进制格式的密文进行解密

如果需要解密的是一个很长的二进制文件,那么可以使用以下代码(代码用chatgpt获得的,质量不错)

密钥要转为bytes格式

输入文件: xxx.zip.enc

输出文件:xxx.zip

from Crypto.Cipher import AES  
import os  
  
secret_key = b'xxxxxx' # Convert the secret key to bytes  
input_file = 'xxx.zip.enc'  
output_file = 'xxx.zip'  
  
# Initialize the AES cipher with the secret key and ECB mode  
cipher = AES.new(secret_key, AES.MODE_ECB)  
  
# Get the size of the input file  
file_size = os.path.getsize(input_file)  
  
# Open the input and output files  
with open(input_file, 'rb') as in_file, open(output_file, 'wb') as out_file:  
    # Read and decrypt the input file in chunks  
    while True:  
        chunk = in_file.read(AES.block_size)  
        if len(chunk) == 0:  
            break  
        out_chunk = cipher.decrypt(chunk)  
        out_file.write(out_chunk)  
  
    # Remove any padding from the output file  
    out_file.truncate(file_size - AES.block_size + len(out_chunk))  

自测结果(考虑填充,AES的输出和输入长度一样)

3.CBC 模式

CBC模式与ECB模式的区别:AES.new() 解密和加密重新生成了aes对象,加密和解密不能调用同一个aes对象,否则会报错。为了防止这类错误,写代码无论是什么模式都重新生成AES对象。

代码

from Crypto.Cipher import AES
password = b'1234567812345678' #秘钥,b就是表示为bytes类型
iv = b'1234567812345678' # iv偏移量,bytes类型
text = b'abcdefghijklmnhi' #需要加密的内容,bytes类型
aes = AES.new(password,AES.MODE_CBC,iv) #创建一个aes对象
# AES.MODE_CBC 表示模式是CBC模式
en_text = aes.encrypt(text) 
print("密文:",en_text) #加密明文,bytes类型
aes = AES.new(password,AES.MODE_CBC,iv) #CBC模式下解密需要重新创建一个aes对象
den_text = aes.decrypt(en_text)
print("明文:",den_text)

自测结果

密文: b'\x93\x8bN!\xe7~>\xb0M\xba\x91\xab74;0'
明文: b'abcdefghijklmnhi'

Process finished with exit code 0

4. 填充模式

        前面使用秘钥,还有明文,包括IV向量,都是固定16字节,也就是数据块对齐了。而填充模式就是为了解决数据块不对齐的问题,使用什么字符进行填充就对应着不同的填充模式。

填充模式
模式意义
ZeroPadding用b’\x00’进行填充,这里的0可不是字符串0,而是字节型数据的b’\x00’
PKCS7Padding当需要N个数据才能对齐时,填充字节型数据为N、并且填充N个
PKCS5Padding与PKCS7Padding相似
no padding当为16字节数据时候,可以不进行填充,而不够16字节数据时同ZeroPadding一样

如果你写的python代码需要考虑填充模式,可以参考这一篇博客的代码。

python实现AES加密解密_python aes_Hello_wshuo的博客-CSDN博客

5.最后

        AES是常见非对称加密算法。

AES (Advanced Encryption Standard) 是一种常用的对称加密算法,Python 中可以利用 `cryptography` 库来实现 AES 加密和解密。下面是一个简单的示例,展示如何使用这个库来完成 AES 加密和解密: ```python from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend # 密钥(16字节,即128位) key = b'sixteen_byte_key' def encrypt(plaintext, key): backend = default_backend() cipher_algorithm = algorithms.AES(key) cipher_mode = modes.CBC(b'some_random_iv') # 使用随机初始化向量(IV) # 创建一个Cipher实例并设置操作模式 cipher = Cipher(cipher_algorithm, cipher_mode, backend=backend) # 对象用于进行加密 encryptor = cipher.encryptor() # 将明文分成块(这里我们假设每个块大小为16字节) ciphertext = b'' for i in range(0, len(plaintext), 16): ciphertext += encryptor.update(plaintext[i:i+16]) # 添加填充后的最终块 ciphertext += encryptor.finalize() return ciphertext, cipher_mode.iv def decrypt(ciphertext, key, iv): backend = default_backend() cipher_algorithm = algorithms.AES(key) cipher_mode = modes.CBC(iv) cipher = Cipher(cipher_algorithm, cipher_mode, backend=backend) decryptor = cipher.decryptor() decrypted_text = b'' while True: try: decrypted_text += decryptor.update(ciphertext) except ValueError: # 如果到达了数据的结束 break # 移除填充 padding_length = decrypted_text[-1] if not 0 < padding_length <= 16: raise ValueError("Invalid padding") decrypted_text = decrypted_text[:-padding_length] return decrypted_text.decode() # 返回明文字符串 # 示例用法 plaintext = "Hello, world!" ciphertext, iv = encrypt(plaintext.encode(), key) decrypted_text = decrypt(ciphertext, key, iv) print(f"原文: {plaintext}") print(f"密文: {ciphertext.hex()}") print(f"解密后: {decrypted_text}") ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓翔仔

星光很亮,我们永远胸怀梦想

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值