cryptographyを使って暗号化したファイルをOpenSSLで復号する

タイトルの通りです。

Pythoncryptographyというパッケージがあるのですが、それを使って暗号化したファイルをOpenSSLのコマンドを叩いて復号するのに躓いたのでメモです。

cryptographyで暗号化する

import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding

backend = default_backend()

# どんな長さの暗号化対象が来てもブロックサイズが一定になるように、パディングする
padder = padding.PKCS7(128).padder()


def encrypt(target_data: bytes) -> (bytes, str, str):
    # 初期ベクトル(同じkeyを利用しても結果が毎回ランダムになるように)
    iv = os.urandom(16)

    # 256byteの鍵の生成
    key = os.urandom(32)

    # AESという共通鍵暗号アルゴリズムを利用し、CBCという暗号モードで初期ベクトルを設定する
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    encryptor = cipher.encryptor()

    # パディングする
    padded_data = padder.update(target_data) + padder.finalize()

    # 暗号化する
    encrypted_bytes = encryptor.update(padded_data) + encryptor.finalize()

    # openssl で復号するなら下記のコマンド
    # keyとivを16進数にしているのがポイントです
    print(f'openssl enc -aes-256-cbc -d -in encrypted_mufufu.png -nosalt -K {key.hex()} -iv {iv.hex()} -out out.png')

    return encrypted_bytes, key, iv


def decrypt(encrypted_data: bytes, key: bytes, iv: bytes) -> bytes:
    # AESという共通鍵暗号アルゴリズムを利用し、CBCという暗号モードで初期ベクトルを設定する
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)
    decryptor = cipher.decryptor()
    decrypted_bytes = decryptor.update(encrypted_data) + decryptor.finalize()
    return decrypted_bytes


if __name__ == '__main__':
    with open('mufufu.png', 'rb') as mufufu:
        data = mufufu.read()

    _encrypted_data, _key, _iv = encrypt(data)

    with open('encrypted_mufufu.png', 'wb') as mufufu:
        mufufu.write(_encrypted_data)

    decrypted_data = decrypt(_encrypted_data, _key, _iv)

    with open('decrypted_mufufu.png', 'wb') as mufufu:
        mufufu.write(decrypted_data)

実行する

python main.py 
openssl enc -aes-256-cbc -d -in encrypted_mufufu.png -nosalt -K 66c7622c137739fa8d1c10111695188d966d10dfec70e26f5905ea11da57bbb3 -iv 5c81d38913ef067fb24f9db566518190 -out out.png

このような結果になると思います。

この実行結果をコピーして実行すると、復号されるはずです。