pythonとphpで相互に暗号化/復号化を行う
pythonで `Simple-AES-Cipher` を使って暗号化された文字列を復号化する。
`Simple-AES-Cipher` を使った場合デフォルトの暗号化方式はaes-256-cbcで、initialization vectorにランダムの文字列が使われる。
返り値はinitialization vector + 暗号化された文字列のbase64となる。
phpでは以下の手順をふみ、復号化する。
以下テストコード。
'12345678901234567890123456789012' を共通で使用するkeyとする。
from simple_aes_cipher import AESCipher cipher = AESCipher('12345678901234567890123456789012') cipher.encrypt('php man') # 0DbgJCpQDDvH8vNs1teJWaSk3U7mGsEdnA/mfg3r0bw=
<?php $key = "12345678901234567890123456789012"; $encrypted_by_python = '0DbgJCpQDDvH8vNs1teJWaSk3U7mGsEdnA/mfg3r0bw='; $decoded = base64_decode($encrypted_by_python); $iv = substr($decoded, 0, 16); $encrypted = substr($decoded, 16); $encrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, true, $iv); // php man
無事OK。
vi(initialization vector)ってなんだ
initialization vectorはECBモードの脆弱さをなくすために作られたらしい。
CBC暗号モードの初期値は、敵から見えてもかまわないことになっていますが、毎回違う値を利用することが推奨されています。
ふーむ。
CBCモードでは、前の平文ブロックを暗号化した結果を次の平文に XOR 演算によって重ね合わせ、その結果に対して暗号化処理を行います。
なるほど。ECBモードに存在した、
- 同じ鍵で暗号化したデータは同じ暗号文になるため、元の平文データを推測しやすい。仮にphp manの暗号文がxxx だった場合、xxxという暗号文はphp manという事がわかってしまう。
- 改ざん検知機能がない
っていうのを改善しているわけだ。改ざん検知機能は不産物感あるな。