本文主要解决的问题
本文主要是讲解AES加密算法中的ECB模式的加密解密的Python3.7实现。具体AES加密算法的原理这里不做过多介绍,想了解的可以参考文末的参考链接。
主要解决了两个问题:
- 在Python3.7版本下,所依赖包的安装问题。(有一些博客时间久远,其中所提到的模块并不适用于Python3.7)
- 因为Python版本的问题,其他博客在基于Python3.6下的代码在Python3.7下并不能运行的问题。
背景介绍
在爬虫项目中遇到,某些网站的账号、密码采用了AES的ECB模式进行了加密。
# 加密前的数据
123456asd
# 加密后的数据
3cfeba82c31b6635e8fb085e04529e74
# 密钥
8NONwyJtHesysWpM
使用在线AES加密解密、AES在线加密解密,进行尝试。
经过测试发现,在AES
加密的ECB模式
,填充为pkcs7padding
,数据块为128位
,输出格式为hex
时,得到自己想要的结果。
(这里可以可以根据密文的格式进行判断输出的格式,一般密文以==结尾的输出格式为base64,否则为hex格式)
问题1:Crypto模块安装报错
pip 安装 pycrypto模块,抛如下错误:
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\cl.exe' failed with exit status 2
解决方法:
问题2:网上copy来的代码报错
在网上博客中直接copy来的代码,可能会抛如下错误。
TypeError: Object type <class 'str'> cannot be passed to C code
换个博客,发现依旧是这个错误。
错误原因:
之前版本的代码并不适用于Python3.7。需要进行修改。
修改后的代码:
import base64
from Crypto.Cipher import AES
import binascii
def add_to_16(text):
while len(text) % 16 != 0:
text += '\0'
return text
def encrypt(data, password):
if isinstance(password, str):
password = password.encode('utf8')
bs = AES.block_size
pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
cipher = AES.new(password, AES.MODE_ECB)
data = cipher.encrypt(pad(data).encode('utf8'))
encrypt_data = binascii.b2a_hex(data) # 输出hex
# encrypt_data = base64.b64encode(data) # 取消注释,输出Base64格式
return encrypt_data.decode('utf8')
def decrypt(decrData, password):
if isinstance(password, str):
password = password.encode('utf8')
cipher = AES.new(password, AES.MODE_ECB)
plain_text = cipher.decrypt(binascii.a2b_hex(decrData))
return plain_text.decode('utf8').rstrip('\0')
if __name__ == '__main__':
data = '123456asd' # 待加密数据
password = '8NONwyJtHesysWpM' # 16,24,32位长的密码(密钥)
password = add_to_16(password)
encrypt_data = encrypt(data, password)
print('加密前数据:{}\n======================='.format(data))
print('加密后的数据:', encrypt_data)
decrypt_data = decrypt(encrypt_data, password)
print('解密后的数据:{}'.format(decrypt_data))
参考
AES ECB PKCS5/PKCS7 加解密 python实现 支持中文
python3.7 利用Crypto进行AES解密&加密文件
关注公众号西加加先生
一起玩转Python。