cryptographyを使って暗号化したファイルをOpenSSLで復号する
タイトルの通りです。
Pythonのcryptographyというパッケージがあるのですが、それを使って暗号化したファイルを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
このような結果になると思います。
この実行結果をコピーして実行すると、復号されるはずです。