Длина шифрования AES / CCM и длина открытого текста превышает максимальную длину сообщения - PullRequest
2 голосов
/ 05 июня 2019

Я пытаюсь выполнить шифрование и дешифрование в библиотеке Crypto ++ с использованием шифра AES128 с режимом работы CCM.У меня проблема при попытке зашифровать строку длиннее 16777215 байт.

Мой код:

const int TAG_SIZE = 8;
CCM< AES, TAG_SIZE >::Encryption e;
CCM< AES, TAG_SIZE >::Decryption d;

e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
e.SpecifyDataLengths( 0, plain.size(), 0 );

//Encryption
StringSource ss1(
  plain,
  true,
  new AuthenticatedEncryptionFilter(
    e,
    new StringSink(cipher)
   )
);

d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
d.SpecifyDataLengths( 0, plain.size(), 0 );

//Decryption
AuthenticatedDecryptionFilter df( d,
  new StringSink(recovered)
);
StringSource ss2(
  cipher,
  true,
  new Redirector(df)
);

Когда я пытаюсь зашифровать / расшифровать открытый текст размером с CD (737280000)), Я получаю следующую ошибку:

"вызывается терминатор после создания экземпляра CryptoPP :: InvalidArgument чем (): AES / CCM: длина сообщения 737280000 превышает максимум 16777215"

Мой вопрос: как мне зашифровать / расшифровать открытый текст, который длиннее 16777215 байт?

1 Ответ

3 голосов
/ 05 июня 2019

У меня вопрос, как мне зашифровать / расшифровать открытый текст длиной более 16777215 байт?

Режим CCM указан в NIST SP800-38c . Раздел A.1, Требования к длине, обсуждает максимально простой текст в контексте безопасности. Контекст безопасности - это комбинация {key, iv} (с некоторым отказом от руки).

Я полагаю, у вас есть три варианта. Во-первых, вы можете увеличить длину IV. Чем больше iv, тем более простой текст вы можете зашифровать. Максимальная длина IV равна 13, поэтому она не масштабируется вечно.

Во-вторых, вам нужно повторно набрать или изменить iv, прежде чем вы достигнете максимально простого текста в контексте. Вы можете найти максимальную длину простого текста, используя MaxMessageLength(). Crypto ++ отслеживает количество байтов, обработанных с помощью m_totalMessageLength, но не предоставляется пользовательским программам. Вам придется отслеживать это самостоятельно.

В-третьих, вы можете изменить алгоритмы. Алгоритм, такой как ChaCha20Poly1305 , позволяет шифровать 2 ^ 38-1 64-байтовых блоков. Это чуть меньше 2 ^ 44 байтов или около 256 ГБ. Вы должны быть в безопасности с ChaCha20Poly1305.


Crypto ++ сообщает вам максимальное количество байтов через MaxMessageLength(). В случае CCM он основан на длине iv и отслеживается через m_L в приведенном ниже коде.

lword MaxMessageLength() const
    {return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;}

MaxMessageLength() используется в authenc.cpp. ProcessData() выдает исключение при достижении лимита:

if (m_state >= State_IVSet && length > MaxMessageLength()-m_totalMessageLength)
    throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
m_totalMessageLength += length;

const int TAG_SIZE = 8;
CCM< AES, TAG_SIZE >::Encryption e;
CCM< AES, TAG_SIZE >::Decryption d;

Ваш размер тега немного маловат. Возможно, вы захотите использовать максимальный размер, если ваш протокол это позволяет.


Я рекомендую вам переключать алгоритмы. CCM - это ублюдочный режим, который был стандартизирован в начале 2000-х годов с помощью беспроводной рабочей группы. Затем NIST принял его, потому что он уже был стандартизирован.

На момент стандартизации CCM были доступны лучшие режимы Authenticated Encryption , такие как CWC, OCB, EAX и GCM. К сожалению, ущерб был нанесен. А теперь у вас есть такие алгоритмы, как ChaChaPoly1305 Бернштейна.

Возможно, вы также захотите оформить Сравнение AEAD в вики Crypto ++. Сравнение показывает, что CCM является худшим из аутентифицированных режимов шифрования.

...