Может быть, я, безусловно, поздно, и я, возможно, пропустили предыдущие ответы, но я не нашел четкого заявления о том, как это должно (по крайней мере, ИМХО) производится в соответствии с пакетами 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
awesome. Хорошо, я понимаю. , так что CTR не имеет преимуществ перед ECB, если я просто хочу зашифровать одну или несколько вещей? Я просто хочу хранить несколько паролей через сеансы. Мне даже нужен AES, или я должен использовать что-то более простое? – xster
На самом деле CTR может шифровать любое произвольное количество текста; он преобразует блочный шифр в генератор ключевого потока. Нет фактической причины для ограничения того, что в этом случае количество входов будет кратным размеру блока. –
PyCrypto, кажется, дает ошибку, когда вход не кратен 16 байтам, но – xster