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
犯人はごん
ごん、お前だったのか…