Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Практическая криптография алгоритмы и их программирование
.pdf
Глава 4. Как устроены современные шифры 131
Режим Обратной Связи по Выходу/OFB. С помощью режима обратной
связи по выходу блочный алгоритм шифрования превращается в поточный, правда, с много большей по размеру структурой атомарных элементов. Проще говоря,
мы можем использовать блочный шифр как поточный, если используем режим
ОСВ. В режиме ОСВ также используется синхропосылка.
C
= синхропосылка.
0
Зашифрование: C
Расшифрование: P
= Pi⊕ Ek(P
i
= Ci⊕ Ek(C
i
i−1
i−1
⊕ C
⊕ P
i−1
i−1
).
).
Режим Гаммирования с Обратной Связью/CFB. Этот режим похож на
режим ОСВ, за исключением того, что блочный шифр приобретает свойства уже
самосинхронизирующегося поточного шифра:
Зашифрование: C
Расшифрование: P
= Pi⊕ Ek(C
i
= Ci⊕ Ek(C
i
i−1
i−1
).
).
Режим Гаммирования/CM. В режиме гаммирования блочный шифр обладает свойствами синхронного шифра, построенного на принципе линейного конг-
руэнтного счетчика. В качестве начального заполнения счетчика используется
результат зашифрования синхропосылки с ключом пользователя. Блоки гаммы
получаются путем шифрования «задающей» последовательности:
S
= Ek(синхропосылка).
0
S
= ËÊÑ(S
i
Зашифрование: C
Расшифрование: P
i−1
).
= Pi⊕ Ek(Si).
i
i
= Ci⊕ Dk(Si).
Режимы Triple-DES. Много позже принятия стандартов, описывающих эти
режимы шифрования, комиссия X9.F.1 ANSI приняла набор режимов для Тройного-DES. Особенностью новых режимов стал выбор в качестве блока обратной связи либо блока шифротекста после трех зашифрований, либо после одного зашифрования. Режимы шифрования названы аналогично стандартным, за исключением соответствующей приставки Triple-DES. Например, режим CBC для
Тройного-DES назван Triple-DES Cipher Block Chaining (TCBC). Соответственно режимы связи по блокам названы outer-CBC — после трех зашифрований
и inner-CBC — после одного.
В настоящее время продолжают разрабатываться новые режимы шифрования, и на базе уже созданных продолжают совершенствоваться новые. Одними из
самых интересных являются два, появление которых связано с принятием нового
стандарта шифрования.
Режим Связи с Накоплением/Accumulated Block Chaining (ABC).
Этот режим разработан Ларсом Кнудсеном (Lars Knudsen), известным бельгийским криптоаналитиком, одним из соавторов шифра Serpent — кандидата на уже
прошедший конкурс AES. Алгоритм зашифрования в этом режиме основан на режиме CBC и сводится к следующей последовательности действий:

132 Глава 4. Как устроены современные шифры
Зашифрование Расшифрование
H
= Pi⊕ h(H
i
C
= H
i
i−1
⊕ Ek(Hi⊕ C
). Hi = Ñi-1 ⊕ Dk(H
i−1
). Ci= Hi⊕ h(H
i−1
i−1
).
i−1
⊕ Ci).
Режим выработки имитовставки AES/AES-hash. Этот режим предназначен для использования только вместе с новым стандартом и позволяет вычислять значение хэш-функции по схеме Дэвиса — Мейера (Davies — Meyer). Для
этого используются AES размером блока в 256 битов и такой же длиной ключа и
следующий алгоритм:
256
H
= 2
= H
−1,
⊕ EXi(H
i−1
i−1
),
0
H
i
ãäå x
— 256-битовые блоки открытого текста.
i
После принятия нового стандарта шифрования в NIST было объявлено о поиске и рассмотрении новых более эффективных режимов шифрования. На сегодняшний день в NIST приняты к рассмотрению следующие режимы шифрования:
2D-Encryption Mode (2DEM), Accumulated Block Chaining (ABC), Counter Mode
Encryption (CTR), Integrity Aware Cipher Block Chaining (IACBC), Integrity Aware
Parallelizable Mode (IAPM), Infinite Garble Extension (IGE), Key Feedback Mode
(KFB), Offset Codebook (OCB), Propagating Cipher Feedback (PCFB), Parallelizable
Message Authentication Code (PMAC), Randomized MAC (RMAC), Extended Cipher Block Chaining (XCBC), eXtended Electronic Code Book MAC (XECB) и
AES-hash.
Устройство поточных шифров
Из введения к этой главе можно узнать об основных отличиях между блочными и поточными шифрами. В действительности, говоря о различиях между ними,
мы использовали несколько критериев, однако свели их все к практической реализации механизмов шифрования. Так, мы указали на то, что поточные шифры
должны обладать «памятью»
Кроме разделения на блочные/поточные шифры, существует разделение и
на уровне самих поточных шифров. Поскольку каждый знак открытого текста в
архитектуре поточного шифра не рассматривается как независимая единица, то
возникает очевидный в общем-то вопрос о том, что будет происходить, если при
передаче сообщения в него вкрадется ошибка. Будет ли она распространяться дальше, и если да, то насколько далеко? Больше всего нас, как пользователей и программистов, может заинтересовать вопрос, будут ли все последующие символы
расшифрованы правильно, если один из них был изменен в цепочке шифротекста.
28
Обратите внимание, что в предыдущих разделах шла речь о «памяти» поточных шифров
как о памяти состояний. В данном разделе мы учитываем то, что все поточные шифры наделены
ею, и потому называем «памятью» поточного шифра его способность помнить уже именно сим
волы открытого и шифротекстов.
28
.
-

Глава 4. Как устроены современные шифры 133
Именно по этим признакам и можно создать вполне естественную классифи-
кацию поточных шифров: на синхронные è самосинхронизирующиеся.
В синхронных поточных шифрах для зашифрования используется внутреннее
состояние - именно оно определяет, каким образом будет представлен элемент открытого текста в виде шифробозначения.
Выбор шифробозначения зависит от положения символа открытого текста относительно его начала и не зависит от остальных символов, зашифрованных до
или после него. Можно сказать, что шифр не имеет памяти
29
. Таким образом,
если криптоаналитик изменит один символ шифротекста, то легальный получатель сможет расшифровать остальную часть сообщения без искажений (листинг
4.31 — жирным шрифтом отмечен ошибочно переданный символ шифротекста,
символ X обозначает неверную расшифровку).
Листинг 4.31 (один неверный символ)
Открытый текст: ÏÎÒÎ× НЫЙ
Шифротекст: 20 43 23 65 49 72 18 37
Расшифровка: ÏÎÒÎX ÍÛÉ
С другой стороны, что произойдет, если кто-либо потеряет часть шифротекста (в начале или середине)? Очевидно, весь остальной участок до конца шифротекста будет расшифрован неверно, поскольку изменяется позиция для всех остальных символов и, следовательно, изменяется принцип выбора расшифровывающего преобразования (листинг 4.32).
Листинг 4.32 (пропуск двух символов)
Открытый текст: Ï Î ТОЧНЫЙ
Шифротекст: 43 23 65 49 72 18 37 44
Измененный шифротекст: 43 23 72 18 37 44
Расшифровка: Ï Î XXXX
Поточные шифры, построенные на базе использования сдвиговых регистров с
обратной связью, являются синхронными шифрами. Их применение довольно широко распространено.
Другой класс поточных шифров — самосинхронизирующиеся поточные шифры. Их архитектура такова, что они имеют ограниченную память на свои предыдущие состояния, тем самым устраняя влияние одной ошибки на остальной текст не
сразу, а после нескольких итераций. В этом случае потеря одного или нескольких
знаков не приведет к таким ужасающим последствиям, как изображено в листинге 4.32, — шифр сам «восстановит» верное состояние через несколько символов,
то есть столько, сколько предыдущих состояний шифра используется для зашифрования текущего элемента открытого текста (листинг 4.33). То есть можно говорить о наличии памяти у шифра на несколько предыдущих элементов текста.
29
Опять же памяти о шифротексте, а не памяти о состоянии.

134 Глава 4. Как устроены современные шифры
Листинг 4.33 (пропуск двух символов)
Открытый текст: Ï Î ТОЧНЫЙШИ
Шифротекст: 43 23 65 49 72 18 37 44 76 12
Измененный шифротекст: 43 23 72 18 37 44 76 12
Расшифровка: Ï Î XXÛÉØÈ
Однако и одиночная ошибка здесь даст не одно-единственное искажение, а в
зависимости от того, сколько предыдущих «неверных» состояний будет находиться в памяти шифра и сколько будет реально задействовано в расшифровании
шифротекста.
Листинг 4.34 (один неверный символ)
Открытый текст: ÏÎÒÎ× НЫЙШИФ
Шифротекст: 20 43 23 65 49 72 18 37 76 12 11
Расшифровка: ÏÎÒÎXXЫЙШИФ
Соответственно комбинируя синхронные и самосинхронизирующиеся шифры, можно получить шифры, которые будут учитывать зависимость и от позиции
символа в тексте, и от нескольких предыдущих зашифрованных символов.
Самыми популярными сегодня шифрами являются, пожалуй, два шифра —
шифр RC4, используемый в программных приложениях на персональных компьютерах, и шифр A5 из серии технических протоколов передачи данных GSM для
мобильных устройств и сотовых телефонов.
Шифр RC4 очень прост в реализации, поэтому с него и начнем. С точки зрения архитектуры RC4 состоит из байтового массива гаммы и двух регистров состояния размером также по одному байту. Байтовая размерность делает RC4 простым не только для реализации на персональных компьютерах, но и для различных аппаратных периферийных устройств — криптографических PCI-плат,
PIC-контроллеров и т. д.
Процесс зашифрования абсолютно идентичен процессу расшифрования и состоит в выработке очередных значений для каждого из элементов массива гаммы
и их наложении на шифруемый текст суммированием по модулю 2. Поэтому в листинге 4.35 приведены только две процедуры — процедура разворачивания ключа
setup_rc4() и процедура зашифрования (она же — расшифрования) encode_rc4().
Листинг 4.35
#include "unidef.h"
typedef struct {
uint8_t state[256];
uint8_t a_reg;
uint8_t b_reg;
} RC4_KEY;
#define xchg_pair(a, b) \
do \
{\

Глава 4. Как устроены современные шифры 135
tmp=a; \
a=b; \
b = tmp; \
}\
while(0)
void setup_rc4(RC4_KEY *key, uint8_t *pass, uint16 passlen) {
uint8_t *state = &key->state[0];
uint8_ta=0,b=0,tmp;
int i;
for (i = 0; i < 256; i++) key->state[i] = i;
key->a_reg = 0;
key->b_reg = 0;
for (i = 0; i < 256; i++) {
b = pass[a] + state[i] + b;
xchg_pair(state+i, state+b);
a = (a + 1) % passlen;
}
}
void encode_rc4(RC4_KEY *key, uint8_t *buf, uint32 buflen) {
uint8_t a_reg = key->a_reg, b_reg = key->b_reg;
uint8_t xor, tmp, *state = &key->state[0];
while (buflen--) {
a_reg++;
b_reg = (state[a_reg] + b_reg);
xchg_pair(&state[a_reg], &state[b_reg]);
xor = state[a_reg] + state[b_reg];
*buf++ ^= state[xor];
}
key->a_reg = a_reg;
key->b_reg = b_reg;
}
В функции encode_rc4() массив значений гаммы state формируется с помощью перестановки и динамической замены непосредственно с использованием регистров состояний a_reg и b_reg. Когда возникает необходимость зашифровать
байт данных, для этой цели используется значение, состоящее из суммы двух элементов массива значений гаммы — соответственно по смещению a_reg и b_reg.
По сути, массив гаммы представляет собой большую таблицу замены, изначально
построенную в зависимости от ключа и динамически изменяющуюся в процессе
преобразования данных.
Гораздо более интересна процедура разворачивания ключа, поскольку алгоритм шифрования RC4 допускает использование «гибких» размеров ключа — от 1
бита и до 2048 битов. Но это границы, которые определяет устройство шифра, на
деле же используется от 40 и до 256 битов.
Разворачивание ключа в алгоритме состоит в заполнении начальными значениями массива гаммы. Для этого сам массив заполняется значениями от 0 до
255. Еще один массив такого же размера — массив ключей, заполняется последовательно символами ключа. Если ключ короче 256 байтов, то массив заполня
-

136 Глава 4. Как устроены современные шифры
ется копиями ключа «встык» до полного заполнения. После этого каждый элемент массива переставляют с элементом, номер j
ìóëå j
= jk+ [значение текущего элемента массива гаммы] + [значение
k+1
которого вычисляется по фор-
k
текущего элемента массива ключей]. Суммирование проводится по модулю 256.
Такой способ организации перестановок дает некоторую уверенность в том,
что каждый элемент массива будет подвергнут перестановке и с высокой вероятностью не останется на прежнем месте. Кроме того, данный способ разворачивания ключа очень быстр и эффективно реализуется на современных процессорах.
Шифр RC4, изобретенный в RSA Laboratories в середине 1990-х годов, до сих пор
считается одним из самых быстрых и эффективных.
30
Еще одним любопытным шифром является шифр A5
. Повышенный интерес
к нему, сделавший его популярным, вызван в основном двумя причинами — тем,
что он используется для шифрования каналов передачи данных и голоса в мобильных телефонах, использующих самый распространенный сотовый стандарт
GSM, и тем, что он является ярким представителем шифров на основе Регистров
Сдвига с Линейной Обратной Связью (РСЛОС).
РСЛОС устроены в виде двоичного регистра определенного размера и функции обратной связи (рис. 4.19). Данные получают с регистра по одному биту, считывая значение из самого старшего (или самого младшего, в зависимости от реа-
31
лизации
) áèòà an. После этого все значения регистра сдвигаются влево, самый
старший бит затирается, а младший заполняется с результатом вычисления функции обратной связи от всех значений регистра. В регистрах типа РСЛОС функция
обратной связи обычно представляет собой сумму по модулю 2 нескольких значений битов регистра.
Связь в сотовых телефонах устроена таким образом, что речь сжимается
определенным способом с помощью так называемого речевого кодека, а затем
упаковывается в пакеты, аналогичные по своей структуре пакетам данных в сети
Интернет. После этого пакет зашифровывается и отсылается на базовую станцию, которая передает его соответствующему абоненту сотовой или обычной телефонной сети.
Процессоры, установленные в сотовых телефонах, не обладают большой
мощностью, поэтому алгоритм шифрования не должен быть слишком ресурсоемким и долгим по времени исполнения, поскольку каждый пакет в соответствии со
стандартом GSM должен отправляться на базовую станцию приблизительно каждые 4,6 миллисекунды. Идеальным вариантом является использование поточного
шифра. Именно поэтому A5/1 был создан как поточный, а не блочный шифр.
В его основе находится три регистра типа РСЛОС различной длины R1, R2 и
R3 — соответственно 19, 22 и 23 бита.
Каждый из регистров работает не все время, а в зависимости от мажоритар-
ного значения. Для вычисления этого значения выбраны биты, находящиеся в се-
30
На самом деле в семействе шифров «Ax» существует два алгоритма шифрования A5. Бы
строе шифрование с помощью A5/2, который подвержен ряду серьезных атак на него, и его бо
лее «утяжеленная» версия A5/1. В книге рассматривается последний вариант.
31
Далее описывается вариант «зеркального РСЛОС», где в качестве выхода регистра вы
бирается старший бит и сдвиг проводится влево.
-
-
-

Глава 4. Как устроены современные шифры 137
Ðèñ. 4.19. Архитектура РСЛОС
редине каждого из регистров, — мажоритарные èëè управляющие биты C1, C2
и C3. Когда необходимо получить бит выхода шифрующей системы, сравниваются
значения управляющих битов каждого из регистров. Для тех регистров, значения
которых совпадают со значением большинства, проводят сдвиг. Остальные регистры в прежнем состоянии остаются без изменений.
Например, если значения соответствующих битов равны (1, 0, 1), то будут
модифицированы только первый R1 и третий R3 регистры. Второй регистр R2
останется без изменения. Выход всей системы получается дополнительным суммированием трех старших битов регистров R1, R2 и R3 по модулю 2 (рис. 4.20).
Ðèñ. 4.20. Архитектура A5/1

138 Глава 4. Как устроены современные шифры
Реализовывать функциональность регистров лучше всего с помощью макросов, поскольку сдвиг и суммирование в младший бит проводится без каких-либо
дополнительных зависимостей и параметров (см. листинг 4.36).
Листинг 4.36
#include <stdio.h>
#include <string.h>
#include "unidef.h"
typedef struct {
uint32_t value[2];
uint32_t frame_n;
} A5_KEY;
typedef uint32_t A5_FRAME[7];
uint8_t a5xor_3[8] = {
0, // 000
1, // 001
1, // 010
0, // 011
1, // 100
0, // 101
0, // 110
1 // 111
};
uint8_t a5xor_2[4] = {
0, // 00
1, // 01
1, // 10
0, // 00
};
uint8_t a5_majority[8] = {
0, // 000
0, // 001
0, // 010
1, // 011
0, // 100
1, // 101
1, // 110
1 // 111
};
// двигаем регистр1
#define R1_CLOCK \
do { \
s = r1; \
s >>= 13; \
b=s&1;\
s >>= 5; \
s = a5xor_3[s & 7] ^ b; \
r1 = (r1 << 1) | s; \

Глава 4. Как устроены современные шифры 139
} while (0)
// двигаем регистр2
#define R2_CLOCK \
do { \
s = r2; \
s >>= 20; \
s = a5xor_2[s & 3]; \
r2 = (r2 << 1) | s; \
} while (0)
// двигаем регистр3
#define R3_CLOCK \
do { \
s = r3; \
s >>= 7; \
b=s&1;\
s >>= 13; \
s = a5xor_3[s & 7] ^ b; \
r3 = (r3 << 1) | s; \
} while (0)
Ключ шифра состоит из некоторого ключа сеанса связи, который, вообще го-
32
воря, должен вырабатываться для каждого телефонного разговора заново
,и
сквозного номера шифруемого пакета (см. структуру A5_KEY в листинге 4.36).
В силу этой причины процедура разворачивания ключа и зашифрования представляет собой единое целое.
Листинг 4.36
#define decrypt_A5 encrypt_A5
void encrypt_A5(A5_KEY *key, A5_FRAME *frame) {
uint32_t s, b, i, o, c;
uint32_t round, r1, r2, r3;
// обнуляем регистры
r1=0;
r2=0;
r3=0;
// заполняем регистры первыми 32 битами ключа
i = key->value[0];
for (round = 0; round < 32; round++) {
// заполняем младшие биты регистров
b=i&1;
i >>= 1;
r1 ^= b;
r2 ^= b;
32
Смена ключей на самом деле зависит от настроек программного обеспечения оператора
сотовой связи. К сожалению, большинство российских операторов сотовой связи пренебрегают
вопросами информационной безопасности и конфиденциальности переговоров своих абонентов
в угоду скорости и эффективности обслуживания своих пользователей — ключи меняются
чрезвычайно редко.

140 Глава 4. Как устроены современные шифры
r3 ^= b;
// вычисляем новые значения
R1_CLOCK;
R2_CLOCK;
R3_CLOCK;
}
// заполняем регистры вторыми 32 битами ключа
i = key->value[1];
for (round = 0; round < 32; round++) {
// заполняем младшие биты регистров
b=i&1;
i >>= 1;
r1 ^= b;
r2 ^= b;
r3 ^= b;
// вычисляем новые значения
R1_CLOCK;
R2_CLOCK;
R3_CLOCK;
}
// заполняем синхропосылкой
i = key->frame_n;
for (round = 0; round < 22; round++) {
// заполняем младшие биты синхропосылкой
b=i&1;
i >>= 1;
r1 ^= b;
r2 ^= b;
r3 ^= b;
// вычисляем новые значения
R1_CLOCK;
R2_CLOCK;
R3_CLOCK;
}
// сотня циклов без выхода
for (round = 0; round < 100; round++) {
// смотрим, что нужно двигать
s = (r1 >> 8) & 1;
s <<= 1;
s |= (r2 >> 9) & 1;
s <<= 1;
s |= (r3 >> 10) & 1;
switch (s) {
case 0: case 7:
R1_CLOCK;
R2_CLOCK;
R3_CLOCK;
break;
case 1: case 6:
R1_CLOCK;
R2_CLOCK;
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
