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.

Другие вопросы по тегам