python AES-CBC 加密解密

要弄懂 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 协议》,转载必须注明作者和本文链接
一代咩神
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!