要弄懂 CBC 加密解密,需要先弄清楚其原理,這樣在寫程式碼的時候思路也會清晰很多。
原理可以搜尋 AES-CBC 和 PKCS7Padding,我也是 google、bing 出來的。
這裡就不說了,直接貼程式碼,採用 PKCS7Padding
的方式填充明文。
golang 的在這裡:部落格:golang AES-CBC 加密解密 ,可以跟 python 無縫對接。
注意:
python
的 AES-CBC 加密解密需要pip install pycryptodome
。
import base64
from functools import reduce
from random import choice
from string import digits, ascii_letters, punctuation
from Crypto.Cipher import AES # 需要安裝 pycryptodome
def cbc_encrypt(plaintext: str, key: str):
"""
AES-CBC 加密
key 必須是 16(AES-128)、24(AES-192) 或 32(AES-256) 位元組的 AES 金鑰;
初始化向量 iv 為隨機的 16 位字串 (必須是16位),
解密需要用到這個相同的 iv,因此將它包含在密文的開頭。
"""
block_size = len(key)
padding = (block_size - len(plaintext) % block_size) or block_size # 填充位元組
iv = reduce(lambda x, y: x + choice(digits + ascii_letters + punctuation), range(16), "")
mode = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
ciphertext = mode.encrypt((plaintext + padding * chr(padding)).encode())
return base64.b64encode(iv.encode() + ciphertext).decode()
def cbc_decrypt(ciphertext: str, key: str):
"""
AES-CBC 解密
密文的前 16 個位元組為 iv
"""
ciphertext = base64.b64decode(ciphertext)
mode = AES.new(key.encode(), AES.MODE_CBC, ciphertext[:AES.block_size])
plaintext = mode.decrypt(ciphertext[AES.block_size:]).decode()
return plaintext[:-ord(plaintext[-1])]
if __name__ == '__main__':
key = "hwWe\mS2`kvu8,z/|hvop7^~)ZUgQhHT" // 32位 AES-256
ciphertext = cbc_encrypt('{"code":200,"data":{"apts":[]},"message":"","success":true}', key)
print(ciphertext)
plaintext = cbc_decrypt(ciphertext, key)
print(plaintext)
本作品採用《CC 協議》,轉載必須註明作者和本文連結