AES получают разные результаты, используя один и тот же ключ и iv для многократного шифрования одного и того же текста
Вот мой код:
from Crypto.Cipher import AES
import binascii
def encrypt(secret_key, sign, raw):
key = md5(secret_key).hexdigest()[::-2]
iv = md5(sign).hexdigest()[::-2]
raw += (16 - len(raw) % 16) * '\0'
generator = AES.new(key, AES.MODE_CBC, IV=iv)
#***********************************************
#Problems occur at here !
#If I execute "generator.encrypt(raw)"
#The results are not same every time
print generator.encrypt(raw) # result_1
print generator.encrypt(raw) # result_2
print generator.encrypt(raw) # result_3
#***********************************************
return binascii.b2a_hex(generator.encrypt(raw))
Я получу разные результаты, когда каждый раз, когда я выполню "generator.encrypt(raw)", это очень смущает меня, потому что я использовал те же KEY и IV.
Я хочу создать API-систему, мне нужно, чтобы другие публиковали свои криптографические данные независимо от того, какой язык они использовали, просто хочу получить тот же результат в AES.
Как я могу получить стабильный результат при использовании AES?
Я имею в виду, что хочу получить тот же результат, когда я использую один и тот же ключ и IV для шифрования одного и того же открытого текста.
1 ответ
AES
Реализация в Pycrypto является состоянием для режима CBC. Это состояние может быть смоделировано значением IV. Давайте предположим, что raw
короче 16 байт для простоты.
В этом случае код
raw += (16 - len(raw) % 16) * '\0'
generator = AES.new(key, AES.MODE_CBC, IV=iv)
print generator.encrypt(raw) # result_1
print generator.encrypt(raw) # result_2
print generator.encrypt(raw) # result_3
эквивалентно
raw += (16 - len(raw) % 16) * '\0'
generator = AES.new(key, AES.MODE_CBC, IV=iv)
ct1 = generator.encrypt(raw)
print ct1 # result_1
generator = AES.new(key, AES.MODE_CBC, IV=ct1)
ct2 = generator.encrypt(raw)
print ct2 # result_2
generator = AES.new(key, AES.MODE_CBC, IV=ct2)
ct3 = generator.encrypt(raw)
print ct3 # result_3
Причина в том, что IV продвигается внутри в соответствии с определением режима CBC. Это означает, что для IV установлен последний полный блок зашифрованного текста.
Если raw
предполагается, что это любая длина, тогда следующее будет эквивалентно, когда только последний блок зашифрованного текста используется в качестве IV для следующего шифрования:
raw += (16 - len(raw) % 16) * '\0'
generator = AES.new(key, AES.MODE_CBC, IV=iv)
ct1 = generator.encrypt(raw)
print ct1 # result_1
generator = AES.new(key, AES.MODE_CBC, IV=ct1[-16:])
ct2 = generator.encrypt(raw)
print ct2 # result_2
generator = AES.new(key, AES.MODE_CBC, IV=ct2[-16:])
ct3 = generator.encrypt(raw)
print ct3 # result_3
Если вы не хотите этого, то вам нужно инициализировать generator
с оригинальной IV.