本文主要解決的問題
本文主要是講解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。