Определить режим AES
Скажем, у меня есть API, который принимает открытый текст и IV в качестве входного параметра и возвращает зашифрованный текст. Я знаю, что API использует шифрование AES 128, но теперь мне нужно определить, какой режим шифрования (ECB, CBC, OFB, CFB или CTR) он использует. Как я могу определить режим шифрования? Мы будем очень благодарны за любые предложения, подсказки или рекомендации.
Пример:
curl "http://dev/api/v1.0/test?iv=00112233445566778899&text=01234567"
Отклик:
7fcb5212d14de7ddcc334ec31acec6ae
Ответы
У вас есть черный ящик, который шифрует данные, и вы работаете в предположении, что этот черный ящик реализует популярный режим (ECB, CBC, CTR, OFB или CFB) (неаутентифицированного) шифрования через блочный шифр. Вы можете отправить входные открытые тексты для шифрования, а также IV по вашему выбору.
Во-первых, вы можете легко различать потоковые режимы и непотоковые режимы:
- CTR, OFB и CFB - это режимы потокового шифрования. Зашифрованный текст всегда имеет ту же длину, что и открытый текст.
- ECB и CBC могут шифровать только целые блоки. Длина зашифрованного текста всегда кратна длине блока (16 байтов для AES, Camellia, ARIA, SM4).
- Существуют непотоковые режимы, для которых зашифрованный текст имеет ту же длину, что и открытый текст, например CTS поверх режима, такого как CBC или XEX. Но я не буду рассматривать их в этом анализе.
Так зашифруйте 1 байт. Если вы получаете 1 байт зашифрованного текста, это потоковый режим. Если вы получаете 16 байт, это режим целого блока с заполнением. Если вы получаете сообщение об ошибке, но шифрование 16 байт работает, это режим целого блока без заполнения.
Режимы заполнения и блока
ЕЦБ фактически не использует IV. Итак, если вы получаете один и тот же результат независимо от IV, это ECB, в противном случае, вероятно, это не так. Но если это странно спроектированная система, IV может использоваться нестандартным образом, например, «квази-ECB» может использовать ECB для открытого текста IV +.
Зашифруйте два одинаковых блока. Если первые два блока зашифрованного текста идентичны, это ECB. В противном случае, по исключению, это CBC. (Третий блок может быть, а может и не быть, в зависимости от метода заполнения.)
Заполнение CBC (или ECB) обычно увеличивает размер зашифрованного текста на 1–16 байтов. Причина, по которой заполнение всегда составляет не менее 1 байта, заключается в том, чтобы сделать дешифрование однозначным: если бы были случаи пустого заполнения, было бы невозможно определить, глядя на дешифрованный, но еще не заполненный шифротекст. Большинство методов заполнения передают длину заполнения через значение последнего байта дешифрованного, но еще не заполненного зашифрованного текста. Однако можно разрешить пустое заполнение, если длина открытого текста передается отдельно или если открытый текст имеет известные свойства, такие как окончание определенным байтом. (Это плохая идея, но здесь мы говорим об анализе плохо спроектированной системы.)
Отличительные режимы потоковой передачи
(Обозначения: $E$ это функция блочного шифрования, $||$ это конкатенация строк, $\oplus$ побитовый xor, $+$ сложение значений счетчика, $\mathbf{0}$ это нулевой блок, состоящий только из битов, $\mathbf{1}$ это блок, в котором все биты равны нулю, за исключением последнего бита 1.)
Поскольку вы можете отправлять один и тот же IV для шифрования несколько раз, можно различать режимы потока. Давайте посмотрим, как двухблочный открытый текст$P_1 || P_2$ зашифрован в двухблочный зашифрованный текст $C_1 || C_2$:
- OFB: $C_1 = E(\mathrm{IV}) \oplus P_1$, $C_2 = E(E(\mathrm{IV})) \oplus P_2$
- CFB: $C_1 = E(\mathrm{IV}) \oplus P_1$, $C_2 = E(E(\mathrm{IV}) \oplus P_1) \oplus P_2$
- CTR: $C_1 = E(\mathrm{IV}) \oplus P_1$, $C_2 = E(\mathrm{IV}+1) \oplus P_2$
Давайте воспользуемся этим, чтобы построить способ различать эти три режима.
- Зашифруйте одноблочный открытый текст с нулевым битом и нулевым битом IV. Независимо от того, какой из этих трех режимов реализует черный ящик, на выходе будет$E(\mathbf{0})$.
- Зашифруйте одноблочный открытый текст с нулевыми битами с помощью IV $E(\mathbf{0})$. На выходе$E(E(\mathbf{0}))$.
- Зашифруйте одноблочный открытый текст с нулевыми битами с помощью IV $\mathbf{1}$(все биты равны нулю, за исключением того, что последний бит равен 1). На выходе$E(\mathbf{1})$.
- Зашифруйте одноблочный открытый текст с нулевыми битами с помощью IV $E(\mathbf{0}) \oplus \mathbf{1}$. На выходе$E(E(\mathbf{0}) \oplus \mathbf{1})$.
- Теперь зашифруйте двухблочный открытый текст: $\mathrm{IV} = \mathbf{0}$, $P_1 = \mathbf{1}$, $P_2 = \mathbf{0}$. Посмотрите на второй блок зашифрованного текста.
- OFB: $C_2 = E(E(\mathbf{0}))$ (рассчитывается на шаге 2).
- CFB: $C_2 = E(E(\mathbf{0}) \oplus \mathbf{1})$ (рассчитывается на шаге 4).
- CTR: $E(\mathrm{0} + 1)$. Обычно это$E(\mathrm{1})$ (рассчитывается на шаге 3), но может отличаться, если реализация CTR по-другому увеличивает счетчик.
Как я могу определить режим шифрования?
Вы не можете полностью определить этот режим, не посылая $2^{64}$Это количество байтов данных под одним и тем же ключом, поскольку только тогда режимы потоковой передачи (CFB, OFB, CTR) начинают по-разному нарушать безопасность.
Однако вы можете быть уверены, что если вы видите зашифрованный текст, который не кратен длине блока (16 байтов для AES), то у вас есть один из CFB, OFB или CTR (или режим, аналогичный режиму потоковой передачи, или один, построенный поверх любого из них).
Теперь, если вы всегда получаете выходные данные, кратные длине блока, то вполне вероятно, что это режим CBC или ECB. Вы можете различить эти два на основе классической уязвимости ECB, которой нет у CBC: равные блоки входов обрабатываются в равные блоки выходов. На практике это означает, что вы можете просто отправить 32 байта из 0, и если вы получите что-то обратно, показывающее две одинаковые 16-байтовые последовательности, у вас будет ECB, иначе CBC. В качестве альтернативы, если вы указываете разные IV для одного и того же открытого текста и по-прежнему получаете тот же зашифрованный текст, вы также знаете, что используется ECB (хотя CBC IV действительно должны выбираться случайным образом, а не противником ...).