0

私の目標は、平文を暗号化し、Python で特定のキーに基づいて復号化する非常に単純な AES 128 CBC スキームを持つことです。私は pycryptodome フレームワークを使用していますが、AES CBC スキームの例を含むドキュメントが見つかりませんでした。

以下は私のコードです。復号化されたデータは、暗号化前のデータと同じではありません。誰かがここで何がうまくいかないのかを特定するのを手伝ってくれれば素晴らしいでしょう.

key = b'Sixteen byte key'
data = 'Jeevan B Manoj'.encode("UTF-8")
data = pad(data,16)
cipher = AES.new(key, AES.MODE_CBC)
print("data before encryption")
print(data)
ciphertext = cipher.encrypt(data)
cipher = AES.new(key, AES.MODE_CBC)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
4

2 に答える 2

3

tmadamが指摘したように、CBC モードの操作では、初期化ベクトル (IV) が機能する必要があります。IV は一般的に忘れられているため (ランダムなど、一意で予測不可能でなければならないことも)、暗号オブジェクトが初期化されると、Pycryptodome はランダムな IV を作成します。

IV は暗号化ごとに一意である必要があり、復号化に必要です。一般的な方法 (情報源?) は、暗号文の先頭に IV を配置することです (IV は秘密である必要はありません)。

あなたの例を機能させるには:

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

# Do not use raw passwords as keys,
# use a derivation functions to generate keys from them
key = b'Sixteen byte key'  
data = 'Jeevan B Manoj'.encode("UTF-8")
data = pad(data, AES.block_size)
encryptor = AES.new(key, AES.MODE_CBC)
iv = encryptor.IV
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)

ciphertext = encryptor.encrypt(data)
plaintext = decryptor.decrypt(ciphertext)

assert plaintext == data

重要な注意:暗号文と IV は、セキュリティのために認証される必要があります(データが改ざんされることはありません)。そのために、 GitHub で Hans-Peter Jansen が指摘したように、Pycryptodome は EAX や GCM などの AEAD モードを提供します。それらの多くでは、パディングは必要ありません。

于 2018-04-15T15:14:35.757 に答える