日々精進

新しく学んだことを書き留めていきます

PythonでバイナリデータをAES256/CBC/PKCS5Paddingで暗号化・復号するサンプルコード

PyCryptodomeがインストールされている前提。

from Crypto import Random
from Crypto.Cipher import AES

from test.util.test_util import AES_KEY

block_size: int = 32


def test_encrypt_image():
    with open("sample.jpg", "rb") as f:
        plain_image: bytes = f.read()
        iv = Random.new().read(16) # PyCryptodomeのivの長さは16byte固定
        pad = lambda s: s + ((block_size - len(s) % block_size) * chr(block_size - len(s) % block_size)).encode('utf-8')
        cipher: AES = AES.new(AES_KEY.encode("utf-8"), AES.MODE_CBC, iv)
        encrypted: bytes = iv + cipher.encrypt(pad(plain_image))

    with open("sample_encrypted.jpg", "wb") as f:
        f.write(encrypted)


def test_decrypt_image():
    with open("sample_encrypted.jpg", "rb") as f:
        encrypted_data: bytes = f.read()
        iv = encrypted_data[0:block_size]
        cipher: AES = AES.new(AES_KEY.encode("utf-8"), AES.MODE_CBC, iv)
        encrypted_image = encrypted_data[block_size:]
        decrypted: bytes = cipher.decrypt(encrypted_image)
        unpad = lambda s: s[0:-s[-1]]
        plain_image = unpad(decrypted)

    with open("sample_decrypted.jpg", "wb") as f:
        f.write(plain_image)