LoginSignup
1
0

OpenSSL aes-256-cbcで暗号化したファイルをPython pycryptoで復号する話

Last updated at Posted at 2024-05-23

OpenSSL aes-256-cbcで暗号化したファイルをPython pycryptoで復号する

PyCryptoで復号する際、SALTの指定が必要。だが、OpenSSLで暗号化する際にはSALTを指定した記憶が無い。
どうやってSALTを抽出すればいいのか悩んだ結果を記載しておく。

OpenSSLで暗号化と復号化テスト

opensslであればたいていのシステムには入っているので、コマンドラインでの暗号/復号をする際はこれが便利だと思う。

# openssl enc -aes-256-cbc -a -pbkdf2 -in ./plain.txt -out ./crypted.enc -pass pass:'mypassword'
# ls
crypted.enc plain.txt
# cat crypted.enc 
U2FsdGVkX19s4t3BtVIv30+1d5rbOvSwTKMP0cap7NJxuVCKvbRKgk6cDYH4oixt

もちろんopenssl enc -dで解凍も可能。
ちなみに、-iter 未指定時は10000回がデフォルトとのこと。使っているサーバにenc.cが無かったので自分でエビデンス確認していません。以下を参照させていただきました。
opensslコマンドを使って暗号化したり...

pythonで解凍するためのスクリプト

opensslでは、SALTは指定しなくとも暗号化できる。その場合、opensslがランダムに生成しているとのこと。
解凍時、そのSALTはどうやって取得するのかというと、暗号化ファイルの中から抽出できる。
(正直、この辺があってSALTって何の意味があるのか全然理解できていない)

で、それを踏まえて書いたスクリプトが以下。

  • count=10000は上記のページを参考にして設定。
  • SALTはdata[8:16]でencryptedファイルから取得するので事前指定不要。
  • pycrypto使用
decrypt.py
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256
from Crypto.Util.Padding import unpad
from Crypto.Cipher import AES
import base64

def decrypt(data, password, iter_count=10000):
    salt = data[8:16]
    ciphertext = data[16:]

    pbkdf2Hash = PBKDF2(password, salt, 32 + 16, count=iter_count, hmac_hash_module=SHA256)
    key = pbkdf2Hash[0:32]
    iv  = pbkdf2Hash[32:32 + 16]

    cipher = AES.new(key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(ciphertext), 16)

password = b'mypassword'
with open('./crypted.enc', 'r') as f:
    data = base64.b64decode(f.read())
plaintext = decrypt(data, password).decode("utf-8")
print(plaintext)

実行してみる。

# python3 ./decrypt.py 
犯人はごん

ごん、お前だったのか…

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0