私は間違いなく遅れている可能性があり、以前の回答を見落としている可能性がありますが、PyCryptoパッケージに従ってこれを(少なくとも私見で)どのように行うべきかについての明確な声明は見つかりませんでした。
Crypto.Util.Counterパッケージは、呼び出し可能なステートフルカウンターを提供します。これは非常に便利ですが、少なくとも私にとっては、それらを不適切に使用するのは簡単でした。
たとえば、カウンターを作成する必要がありますctr = Counter.new('parameters here')
。メッセージを暗号化するためにカウンターモード暗号オブジェクトによってカウンターが呼び出されるたびに、カウンターはインクリメントされます。これは、優れた暗号化手法に必要です。そうしないと、等しいブロックに関する情報が暗号文から漏洩する可能性があります。
これで、同じ暗号オブジェクトで復号化関数を呼び出すことはできなくなります。これは、その間に、場合によっては数回インクリメントされた同じカウンターを再度呼び出すためです。あなたがする必要があるのは、同じパラメータで初期化された異なるカウンタで新しい暗号オブジェクトを作成することです。このようにして、暗号化が行われたのと同じポイントからカウンターを開始して、復号化が適切に機能します。
以下の作業例:
# Import modules
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Util import Counter
# Pad for short keys
pad = '# constant pad for short keys ##'
# Generate a random initialization vector, to be used by both encryptor and decryptor
# This may be sent in clear in a real communication
random_generator = Random.new()
IV = random_generator.read(8)
# Encryption steps
# Ask user for input and pad or truncate to a 32 bytes (256 bits) key
prompt = 'Input your key. It will padded or truncated at 32 bytes (256 bits).\n-: '
user_keye = raw_input(prompt)
keye = (user_keye + pad)[:32]
# Create counter for encryptor
ctr_e = Counter.new(64, prefix=IV)
# Create encryptor, ask for plaintext to encrypt, then encrypt and print ciphertext
encryptor = AES.new(keye, AES.MODE_CTR, counter=ctr_e)
plaintext = raw_input('Enter message to cipher: ')
ciphertext = encryptor.encrypt(plaintext)
print ciphertext
print
# Decryption steps
# Ask user for key: it must be equal to that used for encryption
prompt = 'Input your key. It will padded or truncated at 32 bytes (256 bits).\n-: '
user_keyd = raw_input(prompt)
keyd = (user_keyd + pad)[:32]
# Create counter for decryptor: it is equal to the encryptor, but restarts from the beginning
ctr_d = Counter.new(64, prefix=IV)
# Create decryptor, then decrypt and print decoded text
decryptor = AES.new(keyd, AES.MODE_CTR, counter=ctr_d)
decoded_text = decryptor.decrypt(ciphertext)
print decoded_text