Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Практическая криптография алгоритмы и их программирование

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
Глава 3. Дешифрование классических шифров 31
Раскрытие шифров простой замены
Самыми простыми с точки зрения теории шифрами являются одноалфавит­ные шифры простой замены. В таком шифре ключом является таблица подстанов­ки, однозначно определяющая, какой символ шифрограммы будет заменять опре­деленный символ исходного текста. Или, говоря в соответствующих терминах, таблица сопоставляет шифробозначения соответствующим шифровеличинам. На­пример, на рис. 3.2 представлена ключевая таблица для шифра Цезаря.
Исходный алфавит:
АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ
Подстановка:
ГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮАБВ
Ðèñ 3.2. Ключевая таблица шифра Цезаря
Шифр Цезаря является частным случаем шифра простой замены. Ключ в шифре Цезаря зафиксирован, и, кроме того, он определяется всего лишь одним числом — количеством символов, на которые необходимо сдвинуть исходный ал­фавит, чтобы получить алфавит подстановки. В классическом варианте алфавит просто сдвигался циклически (удаленные символы дописывались в конец) влево на три буквы. Это означает, что вместо буквы 'А' будет записана буква 'В', вместо 'Б' — буква 'Г' и т. д. А вместо мягкого знака в шифротексте появится буква 'А'.
На языке Perl так (см. листинг 3.4):
3
шифрующее преобразование Цезаря в этом случае выглядит
Листинг 3.4
Сообщение: $opentext = "СООБЩЕНИЕ!";
Шифрующее преобразование: for ($i = 0; $i < length($opentext); $i++) {
$ciphertext = $ciphertext . chr(ord(substr($opentext, $i, 1)) + 3); } print "ciphertext == $ciphertext";
Результат:
3
Язык Perl является очень удобным инструментом для проведения быстрых исследова­ний, создания набросков новых алгоритмов и проверки каких-либо вычислительных фактов там, где не требуется высокое быстродействие программы. Этот замечательный язык позволяет исполнять головокружительные трюки преобразования данных к нужному виду и их модифика­цию с большой эффективностью. При этом он достаточно гибок и менее строг по отношению к программисту, в отличие от формального Си/Си++, которые представляют собой мощный ин струмент, обращаться с которым необходимо очень аккуратно. Именно поэтому в этой главе от дано предпочтение не только языку Си, но и Perl. Хотя, например, в главах, посвященных со временным шифрам и их анализу, это не так. В этих главах основным, безусловно, является именно Си.
-
-
-
32 Глава 3. Дешифрование классических шифров
ciphertext == ФССДЬИРЛИ$
В листинге 3.4 пришлось прибегнуть к приведению типов в Perl. Дело в том, что Perl ориентирован на работу со строками как атомарными неделимыми едини­цами языка. Он поддерживает сложение скалярного целочисленного и строковых типов друг с другом, но не позволяет обратиться отдельно к символам строки. То есть для зашифрования одного символа шифром Цезаря в Perl может потребова­ться две строчки (см. листинг 3.5).
Листинг 3.5
$a = 'А'; $a++; print $a; # выведет символ Б на экран
А вот для целой строки символов приходится использовать различные спосо­бы доступа к элементам строкового массива. Первый из них заключается в испо­льзовании стандартной функции-оператора substr, что и было сделано в листинге
3.4. Второй способ заключается в разбиении строки на символьный массив соот­ветствующего объема, преобразовании его поэлементно как массива с атомарны­ми элементами-символами, а затем приведение снова к строковому виду. Исполь­зование этих двух способов представлено в листинге 3.6.
Листинг 3.6
1) Вариант с использованием substr
$string = "строка символов"; # строка символов substr($string, 2, 3) = "ТРО"; print $string; # сТРОка символов
2) Вариант с разбиением в массив символов
@string_arr = split //, $string; # @string_arr == ('ñ', 'ò', 'ð', 'î', ..., 'ë', 'î', 'â')
$string_arr[2] = 'Ò'; $string_arr[3] = 'Ð'; $string_arr[4] = 'Î'; # @string_arr == ('ñ', 'Ò', 'Ð', 'Î', ..., 'ë', 'î', 'â')
$string = join '', @string_arr; print $string; # сТРОка символов
Имея на руках достаточное количество шифротекстов, зададимся вопросом их криптоанализа. Пусть, например, у нас есть зашифрованное сообщение «ЮУП!ТПГЖСЩЖООП!ТЖЛСЖУОПЖ!ТППВЪЖОЙЖ» и мы знаем об откры­том тексте только лишь то, что он был написан на русском языке и зашифрован с помощью шифра Цезаря. Самый простой способ раскрытия шифра Цезаря, кото­рый конечно же сразу приходит в голову, — это опробовать ключи со всевозмож­ными сдвигами алфавита. Всего возможных вариантов в этом случае будет не бо
-
Глава 3. Дешифрование классических шифров 33
льше размерности алфавита. Затем расшифрованные тексты надо будет просто прочесть и выбрать тот, который выглядит осмысленным (см. листинг 3.7).
Листинг 3.7
Всевозможные ключи:
Всевозможные решения, получившиеся после расшифрования сообщения с помощью каждого из ключей:
Вуаля! Первый же опробованный ключ дал нужный результат. Мы увидели осмысленное сообщение, которое, собственно, и являлось открытым текстом. Ис­ходный текст первой программы, которая осуществляет автоматическое дешиф­рование, приведен в листинге 3.8.
Листинг 3.8
$ciphertext = 'ЮУП!ТПГЖСЩЖООП!ТЖЛСЖУОПЖ!ТППВЪЖОЙЖ"'; for ($k = 1; $k < 33; $k++) {
$opentext = ''; for ($i = 0; $i < length($ciphertext); $i++) {
$opentext = $opentext . chr(ord(substr($ciphertext, $i, 1)) - $k);
34 Глава 3. Дешифрование классических шифров
} print $opentext, "\n";
}
К сожалению, такой метод дешифрования может не сработать даже в самом простом случае. Например, когда сообщение написано на иностранном языке, ко­торого криптоаналитик не знает.
Например, во время Второй мировой войны (еще точнее, в период с 1942 по 1945 год) подразделения военно-морской пехоты США для обеспечения секрет­ной связи содержали в штате целое отделение индейцев из племени навахо, кото­рые кодировали секретные сообщения специальным образом.
Идея использовать язык индейцев навахо для обеспечения секретной свя­зи возникла у Филиппа Джонстона, сына индейского миссионера, прожившего несколько лет среди самих навахо, — одного из немногих белых, кто бегло го­ворил на этом языке. Джонстон к этому моменту уже был ветераном Первой мировой, не понаслышке знавшим, что означает секретная связь и какое значе­ние она имеет для победы в бою. Он также был прекрасно осведомлен о том, что военные с удовольствием перестали бы пользоваться громоздкими и мед­ленными шифровальными машинами. Он даже знал, что по причине их медли­тельности и ненадежности в Первой мировой войне в качестве секретного кода использовался язык индейцев чоктоу. Правда, тогда это не принесло ощути­мых результатов.
Учитывая очень сложную структуру устного языка (письменности у навахо не было), где смысл слова всегда зависит от ситуации употребления самого сло­ва и его связи с окружающими частями речи, да еще и иногда зависит просто от ударения на определенный слог, язык навахо был многообещающей заменой для чоктоу.
У навахо не было алфавита, не было букв и вообще любой письменности. Ни­кто, кроме самих навахо да еще нескольких белых (и что самое главное, среди них не было ни одного японца — именно против них и должна была быть органи­зована секретная связь), не знал индейского языка. Выучить же его за короткий срок, даже имея великолепного учителя, было бы очень сложно. И когда в мае 1942 года Джонстон встретился с генерал-майором военно-морской пехоты Бенд­жамином Воджелом, он убедил его в необходимости попробовать набрать рекру­тов из индейцев навахо специально для создания системы секретной связи. Для этого Джонстон в присутствии генерала в течение 20 секунд вручную зашифро­вал текст сообщения, с которым шифровальная машина справилась бы не мень­ше, чем за полчаса. Убежденный приведенным доказательством, генерал-майор Воджел распорядился набрать аж 200 человек навахо.
Тогда же, в мае 42-го, первые 29 новобранцев прибыли в лагерь близ Пендл­тона, в Калифорнию. Именно эта первая группа стала автором «шифра навахо». Изначально этот шифр состоял из большого военного словаря и соответствующих кодовых фраз, который приходилось запоминать целиком.
Шифротекст состоял из сообщений, в которых шифровальщики сначала пере­водили слова с навахо в английские эквиваленты, а затем из них определенным образом составляли секретное сообщение. Дешифрование усложнялось еще и
Глава 3. Дешифрование классических шифров 35
Ðèñ. 3.3. Новобранцы навахо за работой
тем, что одно и то же английское слово могло быть передано несколькими различ­ными словами языка навахо.
Когда боец-навахо получал сообщение, оно состояло из нескольких несвязан­ных между собой слов на языке навахо. Для начала он должен был перевести каждое слово в английский эквивалент из словаря, который он помнил наизусть. Затем для составления секретного сообщения использовалась только первая бук­ва каждого английского слова. Например, слова wol-la-chee (муравей — Ant), be-la-sana (яблоко — Apple) и tse-nill (топор — Axe) обозначали букву «А». Так что, говоря о военно-морском флоте (на английском — navy), навахо мог бы про­изнести: tsah (игла — Needle) wol-la-chee (муравей — Ant) ah-keh-di-glini (ïîáå­äà — Victory) tsah-ah-dzoh (þêêà — Yucca).
Как уже было сказано, многие буквы английского алфавита имели несколько обозначений на языке навахо. К тому же при кодировании не все слова произно­сились буква за буквой, некоторые сугубо военные термины в языке навахо, есте­ственно, просто отсутствовали. Поэтому их заменяли порой весьма забавными эк­вивалентами, например, слово America заменялось на навахское Ne-he-mah (Наша Мать), подводная лодка стала besh-lo (железная рыба), dah-he-tih-hi (ко­либри) означало «самолет-перехватчик», а debeh-li-zine (черная улица) соответст­вовало «отделению».
Благодаря быстроте и точности навахо американцы выиграли сражение при Иво Джима с минимальными потерями. Во время этой баталии шестеро навахо
4
Полный вариант словаря навахо можно найти на компакт-диске, который прилагается к
книге.
4
36 Глава 3. Дешифрование классических шифров
трудились в круглосуточном режиме два дня подряд. Вшестером они передали больше 800 сообщений, и все безошибочно.
Японские криптоаналитики не смогли даже близко подойти к разгадке кода. Глава японской разведки, генерал-лейтенант Сейзо Арисью, позже произнес фра­зу о том, что все коды армии США (в которых использовались шифровальные ма­шины) были успешно взломаны, кроме тех, что использовались в военно-морских корпусах.
Навахо даже после войны еще долгое время оставался совершенно секрет­ным языком. Только по этой причине индейцы навахо, служившие в войсках ВМФ США, получили заслуженные награды и признание лишь в начале 90-х годов.
Временно отступив для демонстрации исторического ракурса на шифры и коды, вернемся к алгоритмам дешифрования шифров замены. Простое опробо­вание всех ключей эффективно, если ключ получается простым сдвигом на не­сколько букв нижней строки таблицы. Если же это не так и произвольные бук­вы верхней строки назначены произвольным буквам нижней, то опробование всех ключей займет ни много ни мало n! операций — именно столько сущест­вует всевозможных перестановок букв в нижней строке ключа-таблицы. Для русского языка n = 33 и соответственно получается 33! варианта. А это 33! = = 8683317618811886495518194401280000000 различных ключей. Даже если компьютер посчитает их все, прочесть их вряд ли кто-либо сможет. Впрочем, конечно же существует простой метод определить ключ шифра — им является метод частотного анализа или метод подсчета частот монограмм (односимволь­ных включений).
Зная, что шифрованное сообщение
5
написано на русском языке, мы можем подсчитать частоту встречаемости букв русского алфавита в нескольких, доста­точно объемных литературных произведениях на русском языке, затем то же са­мое проделать для сообщения и сравнить результаты.
Для подсчета частот воспользуемся текстом шестой главы этой книги (на са­мом деле неплохо было бы использовать гораздо большее количество текста, те­матически подходящего к открытому тексту, который мы ищем) и небольшой про­граммой на Perl, приведенной в листинге 3.9.
Листинг 3.9
#!/usr/bin/perl -w
# наш алфавит for ($i = ord('А'); $i < ord('Я'); $i++) {
print " ", chr($i); } print "\n";
# будем читать содержимое первого переданного # в командной строке файла
5
Чтобы не разгадывать одну и ту же загадку несколько раз подряд, мы будем стараться
изменять зашифрованное сообщение после того, как раскрыли его.
Глава 3. Дешифрование классических шифров 37
open F, "$ARGV[0]"; $total = 0; while (<F>) {
# разделим считанный блок текста $_ на массив символов @_
@_ = split //, $_;
# подсчитываем частоты каждого символа
for (@_) {
$freq{$_}++; $total++;
} } close F;
# теперь отсортируем по убыванию частоты и выведем их на экран @_ = sort { $freq{$b} <=> $freq{$a} } keys %freq;
# вывод на экран for (@_) {
print $_, " == ", $freq{$_}/$total, "\n"; }
Считывая построчно текст из файла, заданного скрипту в командной строке, собираем в хэш-массиве значения найденных символов и инкрементируем их, как только появляется очередной символ. После этого проводим быструю сортировку хэш-массива с помощью оператора sort (в фигурных скобках к нему описана фун­кция, сравнивающая значения вероятностей появления соответствующих симво­лов: {$freq{$b} <=> $freq{$a}}. Имея два различных символа в качестве аргумен­тов-переменных $a и $b, она возвращает 1, если $a < $b, 0 — если $a = $b и 1 в остальных случаях). Здесь Perl выигрывает в скорости программирования мно­гократно. Нам не пришлось писать своих процедур сортировки, да и обработка данных обошлась явно малой кровью.
Запустив программу «perl freq.pl chapter6.txt > freqs.txt», получим в файле freqs.txt следующие результаты (см. листинг 3.10):
Листинг 3.10. freqs.txt
Î == 0.0886740955078085 È == 0.0653614890516941 Å == 0.065094707463728 Ò == 0.0601900305772743 À == 0.0570296948429067 Ñ == 0.0461326930575222 Í == 0.0453323482936239 Â == 0.0381292454185393 Ð == 0.032177963840834 Ë == 0.0320343122165446 Ì == 0.0311929241314207 Ê == 0.0240719078987872 Ä == 0.0231484331712122 ...
38 Глава 3. Дешифрование классических шифров
Проделаем то же самое с шифрованным текстом, который мы имеем (см. листинг 3.11). Для этого запустим «perl freq.pl cipher.txt > freqs_c.txt» (см. лис­тинг 3.12):
Листинг 3.11 cipher.txt
00000000: 84 24 86 92 96 24 A1 96 | 92 24 97 8A 89 24 95 92 Ä$ÆÒÖ$áÖÒ$×ÊÉ$ÕÒ 00000010: 86 89 94 9C 89 91 91 92 | 24 95 89 8E 94 89 96 91 ЖЙФЬЙССТ$ХЙОФЙЦС 00000020: 92 89 24 95 92 92 85 9D | 89 91 8C 89 25 91 84 90 ТЙ$ХТТЕЭЙСМЙ%СДР 00000030: 24 93 94 8C 9C 8F 92 95 | A0 24 95 88 89 8F 84 96 $УФМЬПТХа$ХИЙПДЦ 00000040: A0 24 89 87 92 24 88 92 | 95 96 84 96 92 9B 91 92 а$ЙЗТ$ИТХЦДЦТЫСТ 00000050: 24 88 8F 8C 91 91 9F 90 | 30 9B 96 92 85 9F 24 90 $ИПМССЯР0ЫЦТЕЯ$Р 00000060: 92 8A 91 92 24 85 9F 8F | 92 24 93 94 92 88 89 90 ТКСТ$ЕЯПТ$УФТИЙР 00000070: 92 91 95 96 94 8C 94 92 | 86 84 96 A0 24 94 84 85 ТСХЦФМФТЖДЦа$ФДЕ 00000080: 92 96 97 24 90 89 96 92 | 88 84 9B 84 95 96 92 96 ТЦЧ$РЙЦТИДЫДХЦТЦ 00000090: 91 92 87 92 24 84 91 84 | 8F 8C 8B 84 32 0D 0A СТЗТ$ДСДПМЛД2*
Листинг 3.12. freqs_c.txt
Ò == 0.152866242038217 Ö == 0.0828025477707006 Ñ == 0.0764331210191083 É == 0.0764331210191083 Ä == 0.0700636942675159 Õ == 0.0509554140127389 Ô == 0.0445859872611465 Ì == 0.0318471337579618 Ð == 0.0318471337579618 Ï == 0.0318471337579618 È == 0.0318471337579618 Å == 0.0254777070063694 Æ == 0.0191082802547771 Û == 0.0191082802547771 ß == 0.0191082802547771 à == 0.0191082802547771 × == 0.0127388535031847 Ç == 0.0127388535031847 Ü == 0.0127388535031847 Ó == 0.0127388535031847 Ê == 0.0127388535031847 Ë == 0.0063694267515923 0 == 0.0063694267515923 Ý == 0.0063694267515923
Попробуем заменить самую частую букву в шифротексте «Т» на «О» — са­мую частую букву в русском языке по собранным нами заранее сведениям. Де­шифруем и получим следующее сообщение:
Д ЖОЦ бЦО ЧКЙ ХОЖЙФЬЙССО ХЙОФЙЦСОЙ ХООЕЭЙСМЙ СДР УФМЬПОХа ХИЙПДЦа ЙЗО ИОХЦДЦОЫСО ИПМССЯР0ЫЦОЕЯ РОКСО ЕЯПО УФОИЙРОСХЦФМФОЖДЦа ФДЕОЦЧ РЙЦОИДЫДХЦОЦСОЗО ДСДПМЛД
Глава 3. Дешифрование классических шифров 39
Теперь можно попробовать сменить «Д» на «И», но, посмотрев в таблицу, мы увидим, что вероятность «Д» в шифротексте несколько меньше и «Д» стоит на пя­том месте, вместо положенного второго, а вот «А» стоит как раз на пятом месте. Пробуем заменить:
А ЖОЦ бЦО ЧКЙ ХОЖЙФЬЙССО ХЙОФЙЦСОЙ ХООЕЭЙСМЙ САР УФМЬПОХа ХИЙПАЦа ЙЗО ИОХЦАЦОЫСО ИПМССЯР0ЫЦОЕЯ РОКСО ЕЯПО УФОИЙРОСХЦФМФОЖАЦа ФАЕОЦЧ РЙЦОИАЫАХЦОЦСОЗО АСАПМЛА
Фрагмент «САР» в тексте уже очень похож на «ТАК». Тем не менее, сверив­шись с таблицей вероятностей, принимаем решение не делать соответствующие замены — буквы слишко далеко отстоят друг от друга. Фрагмент «ЖОЦ» в самом начале может быть похож на «ВОТ»; пришлось отвергнуть по тем же причинам. Остается пробовать все известные союзы и предлоги, пробуя делать соответству­ющие замены. В результате «ЖОЦ», замененный на междометие «ВОТ», оказался верным решением. Аналогично «бТО» оказался замененным «ЭТО» и так далее, пока не получилось вот что:
А ВОТ ЭТО УЖЕ ХОВЕФЬЕННО ХЕОФЕТНОЕ ХООЕЭЕНМЕ НАМ УФМЬПОХа ХИЕПАТа ЕЗО ИОХТАТОЫНО ИПМННЯМ0ЫТОЕЯ МОЖНО ЕЯПО УФОИЕМОНХТФМФОВАТа ФАЕОТУ МЕТОИАЫАХТОТНОЗО АНДПМЛД
Слова «ХОВЕФЬЕННО ХЕОФЕТНОЕ» есть не что иное, как «СОВЕРШЕН­НО СЕКРЕТНОЕ». Осуществив замены новых «раскрученных» букв, получаем почти все сообщение. Продолжив это занятие, получаем то самое совершенно секретное сообщение.
Надо заметить, что, если бы у нас были большие словари, в котором находи­лись все словоформы большинства русских слов на определенные тематики, мы могли бы подбирать слова для «отгадки» автоматически, проверяя всевозможные слова и выбирая наиболее «близкие» к словам с дешифрованными фрагментами.
Для этого можно отбирать одинаковые слова по следующему принципу:
слова из словаря и дешифрованного фрагмента должны быть одной длины;
слова одной длины сравнивать по количеству совпадающих в соответствую­щих местах дешифрованных букв.
Например, для фрагмента «ХОВЕФЬЕННО» из нашего примера алгоритм мог бы выдать следующую статистику:
ÕÎÂÅÔÜÅÍÍÎ - СОВЕРШЕННО = 7 ХОВÅÔÜÅÍÍÎ - НЕСЕРЬЕЗНО = 4 ХОВЕФЬЕНÍÎ - РУГАТЕЛЬНО = 2 ...
Руководствуясь ею, мы можем подбирать и угадывать наиболее вероятные слова гораздо быстрее. Создать же такую полезную программу чрезвычайно про­сто. Следует отметить, что если алгоритм реализован итерационно (замена букв происходит поочередно, а не одновременно), то в такой программе нужно преду­смотреть механизм, отличающий прошедшую замену букву от исходной (напри­мер «О», получившуюся из «Т», от «О» из исходного текста)
40 Глава 3. Дешифрование классических шифров
Имея, допустим, достаточно длинный шифротекст и богатый словарь языка, на котором предположительно написано сообщение, мы можем анализировать не­сколько параметров текста, чтобы создать критерий верности дешифровки. Имея такой критерий, мы могли бы создать программу, которая решала бы задачу крип­тоанализа автоматически.
Что могло бы подойти в качестве такого критерия? Наверняка уже опробо­ванный нами способ подсчета частот появления монограмм. Чем ближе будут зна­чения подсчитанных частот к среднестатистическим, тем более вероятно, что шифр раскрыт. С другой стороны, тексты разной тематики дают достаточно раз­ную картину распределения частот, и соответственно, имея разные изначальные данные, мы можем никогда не достичь верного решения.
К сожалению, если мы попробуем увеличить точность метода, подсчитывая не монограммы, а биграммы или даже диграммы (четырехбуквенные сочетания), то заметно увеличим и разрыв между разными видами текстов. Тем не менее под­счет биграмм и диграмм более предпочтителен. Кроме того, что они точнее позво­лят нам определить, насколько дешифрованный текст соответствует исходному, мы дополнительно можем мгновенно отбрасывать варианты, в которых встреча­ются так называемые «запрещенные биграммы и диграммы». Запрещенными их называют потому, что в естественных языках (или других структурированных объектах, например записях баз данных) либо вероятность встретить их прене­брежимо мала, либо их комбинация в этом языке вовсе отсутствует. Например, пары букв «ЫЫ» и «ЩЙ» в русском языке точно не присутствуют, аналогично им в английском отсутствуют «WZ», «YY» и «BX». Таких биграмм (или даже диг­рамм, в зависимости от аппетитов криптоаналитика) можно набрать довольно много. Использование их в криптоанализе просто ускоряет сам процесс, посколь­ку избавляет от множества лишних вычислений. Единственное, что нужно по­мнить в этом случае, так это то, что внесение новых пар необходимо осуществ­лять с осторожностью, поскольку если внести, например, пару «TH» из англий­ского языка в «черный» список, то система заведомо будет вычеркивать почти все верные решения.
6
Попробуем собрать все сведения о взломе шифров замены, которые у нас ока­зались на данный момент. Тогда мы сможем проводить проверку по словарю, под­считывать частоты монограмм и частоты диграмм.
Собрав все это в один программный модуль, получим программу, которая очень сильно облегчила бы жизнь в свое время многим шпионам, — получим про­грамму автоматического дешифрования шифра простой замены.
В целях упрощения мы будем использовать алфавит, состоящий только из русских заглавных букв и пробела. Для начала нам понадобятся средние значе­ния частот появления монограмм и диграмм в русском языке. Для их подсчета воспользуемся программой из листинга 3.13 (впоследствии мы объединим все программы в одну, управляемую ключом компиляции).
6
Дело в том, что на самом деле пара «TH» представляет собой самую часто встречаемую пару символов в текстах на английском языке. Вычеркивая ее, мы тем самым вычеркиваем бо льшинство английских слов и соответственно верных текстов.
-
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]