Основы криптографии

 















ДИПЛОМНАЯ РАБОТА

ОСНОВЫ КРИПТОГРАФИИ


Оглавление

криптография протокол алгоритм ключ

Введение

История, предпосылки и необходимость

Теория

Протоколы

Протоколы с посредником

Арбитражные протоколы

Самодостаточные протоколы

Попытки вскрытия протоколов

Передача информации с использованием симметричной криптографии

Передача информации с использованием криптографии с открытыми ключами

Цифровые подписи

Подпись документа с помошью симметричных криптосистем и посредника

Подпись документа с помошью криптографии с открытыми ключами

Сообщения и ширование

Алгоритмы и ключи

Симметричные алгоритмы

Алгоритмы с открытым ключом

Криптоанализ

Безопасность алгоритмов

Вскрытие шифра простой замены

Взлом многоалфавитных шифров

Теория информации

Энтропия и неопредленность

Норма языка

Расстояние уникальности

Путаница и диффузия

Арифменика вычетов

Простые числа

НОД

Обратные значения по модулю

Функция Эйлера

Квадратичные вычеты

Символ Лежандра

Символ Якоби

Вычисления в поле Галуа

Разложение на множители

Простое XOR

Одноразовые блокноты

Управление ключами

Генерация ключей

Накопление ключей

Алгоритм Диффи-Хеллмана

Использование «блуждающих» ключей

Формальный анализ протоколов проверки подлинности и обмена ключами

Практика

DES

Описание DES

Схема алгоритма

Начальная перестановка

Преобразование ключа

Перестановка с расширением

Постановка с помощью S-блоков

Перестановка с помощью P-блоков

Заключительная перестановка

Дешифрование DES

Безопастность DES

Слабые ключи

Полуслабые ключи

ГОСТ

Основной шаг криптопреобразование

Базовые циклы криптографических преобразований

Основные режимы шифрования

Гаммирование

Выработка иммитовставки к массиву данных

RSA

Шифрование RSA

Скорость RSA

Безопасность RSA

Вскрытие в выбранным шифротекстом против RSA

Вскрытие общего модуля RSA

Вскрытие шифрования и подписи с использованием RSA

Шифр Эль Гамаля

Цифровые подписи

Описание DSA

Подписи DSA

Шифрование Эль Гамаля с DSA

Шифрование RSA с DSA

Заключение

Список испльзованной литературы

Приложения

DESCoding


Введение


Криптография - по сути, одно из самых древних явлений, порожденных человеком. Как только человек стал homo sapiens sapiens, пройдя стадию homo Sapiens prasapiens- у него начали появляться секреты. Секрет - само собой разумеется, не подлежит разглашению, поэтому для того, чтобы его передать, требовалось какое-то средство для его целостной передачи. Таким средством по началу стал.... язык. Да да! Именно язык- ибо не будь у одного племени секретов от другого (например рецепт приготовления мамонта) - то все люди на земле пользовались бы одним и тем же языком.

Но позже выяснилось, что данный метод имеет несколько существенных ограничений - по крайней мере, удержать, таким образом тайну в племени становилось труднее, и поэтому рецепт приготовления мамонта (понятно что не просто так, а за хорошую бронзовую кувалду) становился известен всем.....

Но, как известно, а точнее неизвестно, сильнее щит или меч, человечество изобрело, в порядке хронологии, с начало письменность а потом и метод сокрытия письма - так например Кай Юлий Цезарь использовал простейших (и в то же время первый из общепризнанных) кодов - так называемую подстановку Цезаря - простое смещение алфавита на 13 символов. Хотя с точки зрения 21-го века... ммм... слабовато...

Но, несмотря на всё вышесказанное, кое что в науке о шифрах (crypto- зашитить graphy-писать, или, криптология, что переводится как: kryptos-тайный logos-наука) кое-что осталось неизменным - это Протоколы, алгоритмы, ключи, пароли - объяснения этого и других слов и их более широкий смысл я постараюсь дам попозже, а пока…

История, предпосылки и необходимость


Решительно нет никакой возможности понять пути развития человеческого общества в отрыве от его жгучего стремления к тайнам. Политики и военные, священники и торговцы, писатели и ученые, шарлатаны и аферисты тысячелетиями развивали науку о секретах, доводя их создание до совершенства, служили тайнам, насыщали свои потребности в них. Без тайн не может быть не только государства, но даже малой общности людей - без них нельзя выиграть сражение или выгодно. продать товар, одолеть своих политических противников в жестокой борьбе за власть или сохранить первенство в технологии. Тайны составляют основу науки, техники и политики любой человеческой формации, являясь цементом государственности. История хранит так много секретов, что просто удивительно, до чего людям они необходимы. Служба безопасности пытается делить их на ряд уровней: от для служебного пользования до совершенно секретно и сугубо доверительно. Американский физик Ричард Фейнман шутил, что при работе над созданием атомной бомбы ему наряду с документами, имеющими пометку ingest after reading, то есть буквально съесть после прочтения, попадались иногда бумаги и со штампом уничтожить до прочтения. Сколь ни высоконаучная теория, лежащая в основе такой классификации, она сводится к заурядной дискриминации групп людей, нарушая их естественные права. Если финансовые хищения юридически можно делить на мелкие и крупные, то степень секретности классифицировать абсурдно. Доклад Хрущева на XX съезде партии о культе личности Сталина представлялся секретным лишь для партаппарата, но не для большинства обывателей, прекрасно знавших положение в обществе. Секрет для каждого конкретного человека либо есть, либо его нет. Более того, вскрытие тайны аналитически не только не составляет преступления, а являет торжество человеческого разума и должно приветствоваться, если делается открыто, из лучших побуждений. Французы говорят: "Удел богов - создавать тайны, а королей - раскрывать". Действительно, покажите специалистам лишь один узел сложного устройства, и они реконструируют полный его вид, назначение и характеристики. Если биолога спросить, чем питаются черти, то ответ будет однозначным: "Рога и копыта - явные признаки травоядных!" Правительства всех стран мира стремятся лишить людей интимной (личной, для тех кто не понял) жизни: письма читаются, телефоны прослушиваются, багаж и носильные вещи досматривается, за людьми наблюдают. Вместе с тем все больше наши частные сообщения идут по электронным каналам. Сначала были телефоны, потом появились факсы и наконец вовсю заработала электронная почта. Сообщения электронной почты особенно легко перехватывать или сканировать по ключевым словам, что широко делается как правительственными органами, так хакерами и просто любопытными. Международные отправления все без исключения читаются государственными службами. Трогательно наивные люди, верящие, будто неприкосновенность содержания их писем, телеграмм и телефонных разговоров охраняется Конституцией, должны понять: она лишь дает право на такую защиту, но охранять сама не может. У московского международного почтамта нередко можно найти валяющиеся на тротуаре вскрытые письма, так и не дошедшие до получателя. Известная американская киноактриса, ознакомившись со своим досье в ФБР, воскликнула: "Боже, так я всю жизнь купалась в стеклянной ванне на людном перекрестке!"

Но (опять это но!), начнём, пожалуй, все по-порядку - ибо, криптография, как считают многие (да и я в том числе), условно делится на несколько частей, а именно: историю, теорию и практику.

Ряд систем шифрования дошел до нас из глубокой древности. Скорее всего они появились одновременно с письменностью в 4 тысячелетии до нашей эры. Методы секретной переписки были изобретены независимо во многих древних обществах, таких как Египет, Шумер и Китай, но детальное состояние криптологии в них неизвестно. Криптограммы выискиваются даже в древние времена, хотя из-за применяемого в древнем мире идеографического письма в виде стилизованных картинок были примитивны. Шумеры, по-видимому, пользовались тайнописью. Археологами найдены глиняные клинописные таблички, где первая запись замазывалась слоем глины, на котором делалась вторая запись. Происхождение таких странных таблиц могло быть вызвано и тайнописью, и утилизацией. Оттого что число знаков идеографического письма было более тысячи, то запоминание их представляло собой трудную задачу - тут не до шифрования. Тем не менее, коды, появившиеся вместе со словарями, были хорошо известны в Вавилоне и Ассирии, а древние египтяне применяли по меньшей мере 3 системы шифрования. С развитием фонетического письма письменность резко упростилась. В древнем семитском алфавите во 2-м тысячелетии до нашей эры было всего около 30 знаков. Ими обозначались согласные звуки, а также некоторые гласные и слоги. Упрощение письма стимулировало развитие криптографии.

Даже в Библии можно найти примеры шифровок, хотя мало кто это замечает. В книге пророка Иеремии (25,26) читаем: "...а царь Сессаха выпьет после них." Такого царя или царства не было - неужели ошибка писца? Нет, просто порой священные иудейские тексты шифровались простой заменой. Вместо первой буквы алфавита писалась последняя, вместо второй - предпоследняя и так далее. Этот древний метод шифрования назывался атбаш. Читая по нему слово СЕССАХ, на языке оригинала получаем слово ВАВИЛОН, и смысл библейского текста может быть принят даже не верящим слепо в истинность писания.

После падения Римской империи от вторжения варваров в Европе пошли столетия упадка, которые историки образно назвали Темными веками. Все лучшие достижения цивилизации, а вместе с ними и криптология, были утрачены. По свидетельству святого Джерома "весь мир погрузился в руины". Лишь к концу средневековья применение криптографии начинает возрождаться. Например, книга "Экватор Планет", вышедшая в 1390 году и приписываемая Джефри Чосеру, содержит отдельные шифрованные главы.

Эволюция общественной жизни к концу XIV столетия, приведшая к культуре Возрождения, кризису городских коммун, обострению политического противостояния отдельных групп людей, регрессу в развитии общества из-за войн, выдвинула новые факторы усиления позиций криптографии. Появившаяся интеллектуальная элита в виде гуманистов приходит на службу могущественным меценатам, все более отдаляясь от простого народа. В сфере коммуникаций это проявляется тем, что главенствующим языком сообщений становится античная латынь, которая отходит от живого языка даже в Италии. Древние опыты шифрования восстанавливаются и развиваются целой плеядой крупных ученых. Наряду с традиционными применениями криптографии в политике и военном деле возникают неожиданно близкие к нашему времени задачи ее применения для охраны интеллектуальной собственности от преследований инквизицией или заимствования другими учеными. Слова Вергилия из 16 песни "Ада" "Божественной комедии" Данте, приведенные в эпиграфе этой главы, сколь нельзя более верно описывают точку, вокруг которой стала кристаллизовываться средневековая криптология.

В ручных шифрах того времени часто используются таблицы, которые дают простые шифрующие процедуры перестановки букв в сообщении. Ключом в них служат размер таблицы, фраза, задающая перестановку или специальная особенность таблиц. Простая перестановка без ключа - один из самых простых методов шифрования, родственный шифру скитала. Например, сообщение НЕЯСНОЕ СТАНОВИТСЯ ЕЩЕ БОЛЕЕ НЕПОНЯТНЫМ записывается в таблицу по столбцам. Для таблицы из 5 строк и 7 столбцов это выглядит так:


НОНСБНЯЕЕОЯОЕТЯСВЕЛПНСТИЩЕОЫНАТЕЕНМПосле того, как открытый текст записан колонками, для образования шифровки он считывается по строкам. Если его записывать группами по 5 букв, то получится: НОНСБ НЯЕЕО ЯОЕТЯ СВЕЛП НСТИЩ ЕОЫНА ТЕЕНМ. Для использования этого шифра отправителю и получателю нужно договориться об общем ключе в виде размера таблицы. Объединение букв в группы не входит в ключ шифра и используется лишь для удобства записи несмыслового текста.

Более практический метод шифрования, называемый одиночной перестановкой по ключу очень похож на предыдущий. Он отличается лишь тем, что колонки таблицы переставляются по ключевому слову, фразе или набору чисел длиной в строку таблицы. Использовав в виде ключа слово ЛУНАТИК, получим такую таблицу.


ЛУНАТИК475162ЗНОНСБНЯЕЕОЯОЕТЯСВЕЛПНСТИЩЕОЫНАТЕЕНМ

до перестановки


АИКЛНТУ12З4567СНЯННБОЯЕТЕООЕЕПНЯВЛСЩОЫСИЕТЕНМНТЕА

после перестановки

В верхней строке ее записан ключ, а номера под ключом определены по естественному порядку соответствующих букв ключа в алфавите. Если в ключе встретились бы одинаковые буквы, они бы нумеровались слева направо. Получается шифровка: СНЯНН БОЯЕТ ЕООЕЕ ПНЯВЛ СЩОЫС ИЕТЕН МНТЕА. Для дополнительной скрытности можно повторно шифровать сообщение, которое уже было зашифровано. Этот способ известен под названием двойная перестановка. Для этого размер второй таблицы подбирают так, чтобы длины ее строк и столбцов были другие, чем в первой таблице. Лучше всего, если они будут взаимно простыми. Кроме того, в первой таблице можно переставлять столбцы, а во второй строки. Наконец, можно заполнять таблицу зигзагом, змейкой, по спирали или каким-то другим способом. Такие способы заполнения таблицы если и не усиливают стойкость шифра, то делают процесс шифрования гораздо более занимательным.

Архитекторы и исследователи Италии эпохи Возрождения считают, что один из самых важных этапов ренессансной архитектуры связан с именем Леона Батиста Альберти, написавшем десять книг о зодчестве, построившим палаццо Ручеллаи, церковь Иль Джезу и ряд других замечательных произведений зодчества средневековой Италии. Будучи теоретиком искусства, он обобщил опыт гуманистической науки в изучении античного наследия, написав ряд трактатов: "О статуе", "О живописи", "О зодчестве". С другой стороны, криптологи всего мира почитают его отцом своей науки. Главным достижением Альберти в криптологии было изобретение многоалфавитной замены, сделавших шифровку очень устойчивой к вскрытию. Кроме самого шифра он еще подробно описал устройства из вращающихся колес для его реализации.

Этот шифр можно описать таблицей шифрования, иногда называемой таблицей Виженера, по имени Блеза Виженера, дипломата XVI века, который развивал и совершенствовал криптографические системы:


АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯААБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯБ_АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯВЯ_АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮГЮЯ_АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭ....... ЯВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ_АБ_БВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ_А

Каждая строка в этой таблице соответствует одному шифру замены вроде шифра Юлия Цезаря для алфавита, дополненного пробелом. При шифровании сообщения его выписывают в строку, а под ним ключ. Если ключ оказался короче сообщения, то его циклически повторяют. Шифровку получают, находя символ в колонке таблицы по букве текста и строке, соответствующей букве ключа. Этот очень распространенный вид шифра сохранился до наших дней. Например, используя ключ АГАВА, из сообщения ПРИЕЗЖАЮ ШЕСТОГО получаем следующую шифровку:


сообщение:ПРИЕЗЖАЮ ШЕСТОГОключ:АГАВААГАВААГАВААшифровка:ПНИГЗЖЮЮЮАЕОТМГО

В компьютере такая операция соответствует сложению кодов ASCII символов сообщения и ключа по некоторому модулю. Кажется, что если таблица будет более сложной, чем циклическое смещение строк, то шифр станет надежнее. Это действительно так, если ее менять почаще, например, от слова к слову. Но составление таких таблиц, представляющих собой латинские квадраты, где любая буква встречается в строке или столбце один раз, трудоемко и его стоит делать лишь на ЭВМ. Для ручного же многоалфавитного шифра полагаются лишь на длину и сложность ключа, используя приведенную таблицу, которую можно не держать в тайне, а это упрощает шифрование и расшифровывание. Итак, помимо ряда строений в античной манере, являющихся шедеврами архитектуры итальянского Возрождения, Альберти еще ввел в практику криптографии многоалфавитные шифры замены. Его книга "Трактат о шифре", написанная в 1466 году, представляла собой первый в мире научный труд по криптологии, если не считать арабских рукописей, с которыми Европа в это время вряд ли была хорошо знакома.

Многие историки считают Иоганна Трисемуса, аббата из Германии, вторым отцом современной криптологии. В 1508 году Трисемус написал "Полиграфию", первую печатную работу по криптологии. В ней он первым систематически описал применение шифрующих таблиц, заполненных алфавитом в случайном порядке. Для получения такого шифра обычно использовались ключевое слово или фраза и таблица, которая для русского языка может иметь размер 5 Х 6. Ключевое слово вписывалось в таблицу по строкам, а повторяющиеся буквы отбрасывались. Таблица дозаполнялась не вошедшими в нее буквами алфавита по порядку. Поскольку ключевое слово легко хранить в памяти, то такой подход упрощал процессы шифрования и дешифрования. Для ключа РЕСПУБЛИКА таблица будет иметь следующий вид:


РЕСПУБЛИКАВГДЖ3МНОТФХЦЧШЩЬЫЭЮЯ

Для описанного выше шифра Полибия с данной таблицей сообщение ОТПЛЫВАЕМ давало шифровку ШЩАДСНМИЦ. Такие табличные шифры называются монограммными, так как шифрование ведется по одной букве. Трисемус первым заметил, что можно шифровать по две буквы за раз. Такие шифры были названы биграммными. Наиболее известный шифр биграммами называется Playfair. Он применялся Великобританией в Первую мировую войну. Опишем его на примере той же самой таблицы. Открытый текст разбивался на пары букв (биграммы) и текст шифровки строился из него по следующим двум очень простым правилам.

. Если обе буквы биграммы исходного текста принадлежали одной колонке таблицы, то буквами шифра считались буквы, которые лежали под ними. Так биграмма УН давала текст шифровки ВЧ. Если буква открытого текста находилась в нижнем ряду, то для шифра бралась соответствующая буква из верхнего ряда и биграмма ОЯ давала шифр ШБ. (Биграмма из одной буквы или пары одинаковых букв тоже подчинялась этому правилу и текст ЕЕ давал шифр ИИ).

. Если обе буквы биграммы исходного текста принадлежали одной строке таблицы, то буквами шифра считались буквы, которые лежали справа от них. Так биграмма ИВ давала текст шифровки КГ. Если буква открытого текста находилась в правой колонке, то для шифра бралась соответствующая буква из левой колонки и биграмма ОМ давала шифр ДН.

Если обе буквы биграммы открытого текста лежали в разных рядах и колонках, то вместо них брались такие две буквы, чтобы вся четверка их представляла прямоугольник. При этом последовательность букв в шифре была зеркальной исходной паре. Например, СТ шифровалось как РХ, а ТБ шифровалось как ШР. При шифровании фразы ПУСТЬ КОНСУЛЫ БУДУТ БДИТЕЛЬНЫ по биграммам получается такая шифровка:


ПУСТЬКОНСУЛЫБУДУТБДИТЕЛЬНЫУБРХЫИДОПБКЩРБHPШРЖЛФРИЩЗЮ

Шифрование биграммами резко усилило стойкость шифров к вскрытию. При всем при том, что "Полиграфия" была довольно доступной печатной книгой, описанные в ней идеи получили признание лишь тремя веками позже. Скорее всего это вызвано плохой известностью среди криптографов Трисемуса, который слыл богословом, библиофилом и основателем архивного дела.Среди шифров средневековья встречается много курьезов. Леонардо да Винчи шифровал большинство своих личных записей. Самый простой вид шифра которым он пользовался, это обратное написание текста так, что прочесть его можно лишь в отражении зеркала. Однако Леонардо иногда использовал шифры и посерьезнее, поэтому далеко не все его заметки и записи расшифрованы и изучены. Люди, умеющие писать левой рукой справа налево зеркальный текст, нередки. Изумительно, но встречаются люди, которые умеют даже произносить фразы "наоборот" и понимать их на слух. Поистине, человеческим способностям нет и не будет предела!Новое время привнесло новые достижения в криптографию. Постоянно расширяющееся применение шифров выдвинуло новое требование к ним - легкость массового использования, а старое требование - устойчивость к взлому не только осталось, но и было усилено. Поэтому 1854 год, когда англичанин Чарльз Уитстон разработал новую шифровку биграммами, которую называют двойной квадрат, открыл новый этап в криптографии. Название шифр получил по аналогии с полибианским квадратом. В отличие от полибиаиского, двойной квадрат использует сразу две таблицы, расположенные по горизонтали, а шифрование идет биграммами, как в шифре Playfair. Эти, казалось бы и не столь уж значительные изменения привели к появлению на свет новой криптографической системы ручного шифрования. Она оказалась так надежна и удобна, что применялась немцами даже в годы Второй мировой войны. По отзыву ее создателя, шифрование двойным квадратом предельно просто и его "можно доверить даже дипломатам". Приведем пример использования шифра двойной квадрат для русских текстов. Имеются две таблицы со случайно расположенными в них алфавитами:


ЧВЫПОК:ДУГШ3ЭФЛЪХА,ЮРЖЩНЦБИТЬ.СЯМЕЕЛЦ:П.ХЪАНШДЭКСЫБФУЯТИЧГМО,ЖЬВЩ3ЮР

Для шифрования сообщение разбивают на биграммы. Первая буква биграммы находится в левой таблице, а вторая в правой. Затем, мысленно в таблице строится прямоугольник так, чтобы буквы биграммы лежали в его противоположных вершинах. Другие две вершины этого прямоугольника дают буквы шифровки. Предположим, что шифруется биграмма текста ОЖ. Буква О находится в колонке 1 строки 2 левой таблицы. Буква Ж находится в колонке 4 строки 6 правой таблицы. Значит, прямоугольник образован строками 2 и 6, а также колонками 1 левой и 4 правой таблиц. Следовательно, шифровке соответствуют буквы, лежащие в колонке 1 строки 6 левой таблицы Ц и в колонке 4 строки 2 правой таблицы А - биграмма АЦ. Так парами букв шифруется все сообщение:


Сообщение:ПРИЕЗЖАЮШЕСТОГОШифровка :ПЕМБКИФМЕШРФЖБДЦЩПЕсли обе буквы биграммы сообщения лежат в одной строке, то и буквы шифровки берутся из этой же строки. Первая буква биграммы шифровки берется из левой таблицы в столбце, соответствующем второй букве биграммы сообщения. Вторая же буква биграммы шифровки берется из правой таблицы в столбце, соответствующем первой букве биграммы сообщения. Так, по приведенным выше таблицам биграмма сообщения ТО превращается в биграмму шифровки ЖБ. Несомненно, что шифрование биграммами дает весьма устойчивый к вскрытию и простой шифр, а это было в то время крупным успехом. Взлом шифровки двойного квадрата требует больших усилий и длины сообщения более тридцати строк.

Предшественницей современных криптографических машин была роторная машина, изобретенная Эдвардом Хеберном в 1917 году и названная впоследствии Энигмой (Слово enigma переводится как загадка. Промышленные образцы этой машины изготовляла фирма Siemens.). Независимая промышленная ее версия создана чуть позже берлинским инженером Артуром Кирхом (некоторые источники называют его Артуром Шербиусом). Она сначала представляла собой 4 вращающихся на одной оси барабана, обеспечивающих более миллиона вариантов шифра простой замены, определяемого текущим положением барабанов. На каждой стороне барабана по окружности располагалось 25 электрических контактов, столько же, сколько букв в алфавите. Контакты с обеих сторон барабана соединялись попарно случайным образом 25 проводами, формировавшими замену символов. Колеса складывались вместе и их контакты, касаясь друг друга, обеспечивали прохождение электрических импульсов сквозь весь пакет колес. Перед началом работы барабаны поворачивались так, чтобы устанавливалось заданное кодовое слово - ключ, а при нажатии клавиши и кодировании очередного символа правый барабан поворачивался на один шаг. После того, как он делал оборот, на один шаг поворачивался следующий барабан - будто бы в счетчике электроэнергии. Таким образом, получался ключ заведомо гораздо более длинный, чем текст сообщения.Например, в первом правом барабане провод от контакта, соответствующего букве U, присоединен к контакту буквы F на другой его стороне. Если же барабан поворачивался на один шаг, то этот же провод соответствовал замене следующей за U буквы V на следующую за F букву G. Так как барабаны соприкасались контактами, то электрический импульс от нажатой клавиши с буквой исходного текста прежде чем достигал выхода претерпевал 4 замены: по одной в каждом барабане. Для затруднения расшифрования барабаны день ото дня переставлялись местами или менялись. Дальнейшее усовершенствование этой машины сделало движение барабанов хаотичным, а число их увеличилось сначала до 5, а потом до 6. Все устройство могло поместиться в портфеле и было так просто, что обслуживалось обычными связистами.

Казалось бы, сделано все для невозможности вскрытия шифровок Энигмы. И все же английские криптографические службы в Блетчли Парке (уединенное поместье в 80 километрах севернее Лондона, отведенное британским криптологам.) почти всю войну читали немецкие шифры. Это стало возможным лишь благодаря польской разведке, которая к злополучному 1939 году смогла получить чертежи Энигмы и разобраться в ее устройстве. После нападения гитлеровцев на Польшу чертежи немецкой шифровальной машины были переданы Англии. Довольно быстро британские криптоаналитики установили, что для взлома шифра, нужно знать распайку проводов в шифрующих колесах. Началась охота британских спецслужб за образцами Энигмы. Первый удалось выкрасть прямо с завода на юго-востоке Германии, второй сняли со сбитого в небе Норвегии немецкого бомбардировщика, третий был найден во время боев за Францию у немецких военных связистов, взятых в плен. Остальные Энигмы сняты водолазами с немецких подводных лодок, за которыми специально стали охотиться и топить на малых глубинах.Взлом шифров Энигмы шел тяжело до тех пор, пока в 1942 году не вступили в строй несколько ЭВМ, специально созданных для этого Аланом Тьюрингом. Это была первая в мире довольно быстродействующая ЭВМ под названием "Колосс", специализированная для взлома шифров. После этого английские криптоаналитики могли меньше чем за день могли расколоть любую шифровку Энигмы, полученную добытыми ранее колесами, методично перебирая все возможные ключи. Немцы рассчитывали на сложность своего шифра, исходя из его ручной дешифровки, в то время как англичане стали его ломать, используя ЭВМ. Отметим, что сами немцы допускали возможность взлома шифра Энигмы. Еще в 1930 году ведущий немецкий криптоаналитик Георг Шредер продемонстрировал такую возможность, едко заметив при этом: "Энигма - дерьмо!" (пардон, цитирую) Однако она постоянно усложнялась и были периоды, когда в Блетчли Парке с ней не могли справиться. Перед шифровками Энигмы, которые исходили не от войск, а из немецких криптографических центров, "Колосс" тоже был бессилен(недаром есть поговорка-"Чем больше в армии дубов, тем крепче наша оборона", армия в любой стране мира, при любом уровне цивилизация остается армией).

Надеюсь, маленький экскурс в историю, поможет Вам и мне продвинутся дальше.

Теория


Да да, именно с большой буквы, ибо я собираюсь приступить к написанию самой нудной и неинтересной части- теории.

Учтем что мы имеем дело не с Евклидовой геометрией, где всё достаточно просто, а со сложнейшей наукой, призванной охранять секреты одного государства от другого, не менее мощного.. а такого рода действия, требуют довольно больших интеллектуальных вложений. Да и отслеживая историю развития криптографии, от рецепта мамонта до водородной бомбы, можно сделать умозаключение, что наука, насчитывающая под собой несколько десятков тысячелетий (а вполне возможно и миллионы лет), в чём она сродни философии, литературе и музыке, будет иметь довольно обширную и разносторонне развитую теорию.


Протоколы


Нет не подумайте, что я перехожу к Интернету- ни коем случае, по крайней мере пока. Протокол- вообшето, это формальность общения, или "Порядок действий, предпринимаемых двумя или более сторонами, предназначенный для peшения определенной задачи ".

Это важное определение. "Порядок действий" означает, протокол выполняется в определенной последовательности, с начала до конца. Каждое действие должно выполняться в свою очередь и только после окончания предыдущего. "Предпринимаемых двумя или более сторонами" означает, что для реализации протокола требуется по крайней мере два человека, один человек не сможет реализовать протокол. Человек в одиночку может выполнить некоторые действия, решая задачу (например, покупая торт), но это не протокол. (Для того, чтобы получился настоящий протокол, кто-то должен съесть торт.) Наконец, "предназначенный для решения определенной задачи" означает, что протокол должен приводить к какому-то результату. Что-то, похожее на протокол, но не решающее никакой задачи - это не протокол, это потеря времени. У протоколов есть также и другие характеристики:

  • Каждый участник протокола должен знать протокол и последовательность составляющих его действий .
  • Каждый участник протокола должен согласиться следовать протоколу .
  • Протокол должен быть непротиворечивым, каждое действие должно быть определено так, чтобы
  • не было возможности непонимания.
  • Протокол должен быть полным, каждой возможной ситуации должно соответствовать определенное действие.

Криптографический протокол - это протокол, использующий криптографию. Стороны могут быть друзьями и слепо доверять друг другу или врагами и не верить друг другу даже при сообщении времени суток. Криптографический протокол включает некоторый криптографический алгоритм, но, вообще говоря, предназначение протокола выходит за рамки простой безопасности. Участники протокола могут захотеть поделиться секретом друг с другом, совместно генерировать случайную последовательность, подтвердить друг другу свою подлинность или подписать контракт в один и тот же момент времени. Смысл использования криптографии в протоколе - в предотвращении или обнаружении вредительства и мошенничества . Если вы никогда не сталкивались с подобными протоколами, они могут радикально изменить ваше представление о том, что недоверяющие друг другу стороны могут выполнить, используя компьютерную сеть. Общее правило можно сформулировать следующим образом:

ØНевозможно сделать или узнать больше, чем определено в протоколе

Для демонстрации работы протоколов я использую несколько игроков. Первые двое - это А и B. Они участвуют во всех двусторонних протоколах. Как правило, A начинает все протоколы, а B отвечает. Если для протокола нужна третья или четвертая сторона, в игру вступают C и D. Другие участники играют специальные вспомогательные роли, они будут представлены позже.

Для начала, изобразим три основных типа протоколов графически.




Протоколы с посредником


Посредник - это незаинтересованная третья сторона, которой доверено завершение протокола Незаинтересованность означает, что у посредника нет заинтересованности в результате работы протокола и склонности к одной из сторон. "Доверено" означает, что все участники протокола принимают все, что скажет посредник за истину, все его действия - как правильные, и уверены в том, что посредник выполнит свою часть протокола. Посредники помогают реализовать работу протоколов взаимодействия недоверяющих друг другу сторон.

В реальном мире в качестве посредников часто выступают юристы . Например, A продает незнакомому B машину. B хочет заплатить чеком, но у А нет способа проверить, действителен ли чек. A хочет, чтобы расчет по чеку был произведен прежде, чем право собственности перейдет к B . B, который верит А не больше, чем она ему, не хочет передавать чек, не получив права собственности. Обозначим юриста через С

Посредничество юриста устроит обоих. С его помощью A и B могут выполнить следующий протокол, чтобы защитить себя от обмана:

  1. A передает право собственности юристу.
  2. B передает чек юристу.
  3. A депонирует чек.
  4. Дождавшись оплаты чека юрист передает право собственности B. Если чек не оплачен в течение определенного времени, A доказывает этот факт юристу, и тот возвращает право собственности А.

В этом протоколе A верит, что юрист не передаст B право собственности до тех пор, пока чек не будет оплачен, и вернет право собственности А, если чек оплачен не будет. B верит, что юрист будет обладать правом собственности до тех пор, пока чек не будет оплачен, и передаст право собственности B сразу же после оплаты чека. С не заботится об оплате чека.


Арбитражные протоколы


Арбитр, как и посредник, представляет собой незаинтересованного участника протокола, которому доверяют обе стороны. В отличие от посредника он непосредственно не принимает участия в каждой отдельной реализации протокола и приглашается только для проверки честности выполнения протокола сторонами .

Профессиональными арбитрами являются судьи. В отличие от нотариусов к судьям обращаются только при появлении разногласий. A и B могут заключить контракт без участия судьи. Судья никогда не узнает о контракте, если одна из сторон не подаст на другую в суд. Протокол подписания контракта можно формализовать следующим образом:

Подпротокол без посредника (выполняется всегда):

  1. A и B договариваются об условиях контракта.
  2. A подписывает контракт.
  3. B подписывает контракт.

Подпротокол с использованием арбитра (выполняется при наличии разногласий):

  1. A и B предстают перед судьей.
  2. A предоставляет свои доказательства.
  3. B предоставляет свои доказательства.
  4. Судья принимает решение на основании доказательств.

Различие используемых понятий посредника и арбитра состоит в том, что участие арбитра происходит не всегда. Стороны обращаются к судье только при разногласиях. Если разногласий нет, судья не нужен.


Самодостаточные протоколы


Самодостаточный протокол является лучшим типом протокола. Он полностью обеспечивает честность сторон . Для выполнения протокола не нужен ни посредник, не решающий споры арбитр . Само построение протокола обеспечивает отсутствие споров. Если одна из сторон попытается смошенничать, мошенничество будет немедленно обнаружено другой стороной, и протокол прекратит выполняться. Чего бы не пыталась добиться мошенничающая сторона, этому не суждено случиться.


Попытки вскрытия протоколов


Вообще следует заметить что у криптографии могут быть несколько слабых мест- протокол, алгоритм и пароль- пожалуй самые основные. Криптографические попытки взлома могут быть направлены против криптографических алгоритмов, иcпользуемых в протоколах, против криптографических методов, используемых для реализации алгоритмов и протоколов или непосредственно против протоколов. Поскольку в этом разделе книги обсуждаются именно протоколы, я предполагаю, что криптографические алгоритмы и методы безопасны , и рассматриваю только попытки вскрытия протоколов.

Люди могут использовать множество способов взломать протокол. Некоторые, не являясь участниками протокола, могут "подслушивать" какую-то часть или весь протокол. Это называется пассивным вскрытием, так как взломщик не воздействует на протокол. Все, что он может сделать - это проследить за протоколом и попытаться добыть информацию. Этот тип вскрытия соответствует вскрытию с использованием только шифротекста.Так как пассивные вскрытия трудно обнаружить, протоколы стремятся предотвращать, а не обнаруживать их. В этих протоколах роль злоумышленника будет играть Е.

В другом случае взломщик может попытаться изменить протокол для собственной выгоды. Он может выдать себя за другого, ввести новые сообщения в протокол, заменить одно сообщение другим, повторно передать старые сообщения, разорвать канал связи или изменить хранящуюся в компьютере информацию. Такие действия называются активным вскрытием, так как они требуют активного вмешательства. Эти формы вскрытия зависят от вида сети.

Пассивные взломщики стараются получить информацию об участниках протокола . Они собирают сообщения, переданные различными сторонами, и пытаются криптоанализировать их . Попытки активного вскрытия, с другой стороны, преследуют более широкий набор целей. Взломщик может быть заинтересован в получении информации, ухудшении работы системы или получении несанкционированного доступа к ресурсам.

Активные вскрытия более серьезны, особенно в отношении протоколов, в которых стороны не обязательно доверяют друг другу. Взломщик не обязательно кто-то совсем посторонний, он может быть зарегистрированным пользователем системы и даже системным администратором. Может быть даже несколько активных взломщиков, работающих вместе. Роль злонамеренного активного взломщика будет играть F.

Взломщиком может быть и один из участников протокола. Он может обманывать, выполняя протокол, или вовсе не следовать правилам протокола. Такой взломщик называется мошенником. Пассивные мошенники выполняют правила протокола, но стараются получить больше информации, чем предусмотрено протоколом. Активные мошенники нарушают работу протокола, пытаясь смошенничать.

Очень трудно поддерживать безопасность протокола, если большинство его участников - активные мошенники, но иногда активное мошенничество может быть обнаружено законными участниками . Конечно, протоколы должны быть защищены и от пассивного мошенничества.

Передача информации с использованием симметричной криптографии

Как двум сторонам безопасно обмениваться информацией? Конечно же, шифрую свои сообщения. Посмотрим, что должно произойти, когда A посылает шифрованное сообщение B

  1. A и B выбирают систему шифрования.
  2. A и B выбирают ключ.
  3. A шифрует открытый текст своего сообщения с использованием алгоритма шифрования и ключа, получая шифрованное сообщение.
  4. A посылает шифрованное сообщение B.
  5. B дешифрирует шифротекст сообщения с использованием алгоритма шифрования и ключа, получая открытый текст сообщения.

Что может E, находясь между А и B, узнать, подслушивая этот протокол ? Если она может подслушать только передачу на этапе (4), ей придется подвергнуть шифротекст криптоанализу. Это пассивное вскрытие представляет собой вскрытие с использованием только шифротекста, применяемые алгоритмы устойчивы по отношению к любым вычислительным мощностям, который может заполучить Е для решения проблемы.

Е, однако, не глуп. Она может также подслушать и этапы (1) и (2). Тогда ей станут известны алгоритм и ключ - также как и B. Когда она перехватит сообщение на этапе (4), то ей останется только дешифровать его самостоятельно.

В хорошей криптосистеме безопасность полностью зависит от знания ключа и абсолютно не зависит от знания алгоритма. Именно поэтому управление ключами так важно в криптографии. Используя симметричный алгоритм, A и B могут открыто выполнить этап (1), но этап (2) они должны сохранить в тайне . Ключ должен оставаться в секрете перед, после и в течение работы протокола - до тех пор, пока должно оставаться в тайне передаваемое сообщение - в противном случае сообщение тут же будет раскрыто . , активный взломщик, может сделать кое-что другое. Он может попытаться нарушить линию связи не этапе (4), сделав так, что A вообще не сможет передавать информацию B . F также может перехватить сообщение А и заменить его своим собственным. Если ему удалось узнать ключ (перехватив обмен информацией на этапе (2) или взломав криптосистему), он сможет зашифровать свое сообщение и отправить его B вместо перехваченного, и B не сможет узнать, что сообщение отправлено не А. Если F не знает ключа, он может только создать сообщение, превращающееся при дешифровке в бессмыслицу . B, считая, что сообщение отправлено А, может решить, что либо у А, либо в сети возникли серьезные проблемы.

А A? Что она может сделать, чтобы испортить протокол? Она может передать копию ключа Е, и тогда Е сможет читать все, что говорит B, и напечатать его слова в любой газете, но проблема не в протоколе. A и так может передавать Е любые открытые тексты, передаваемые с использованием протокола. Конечно, то же самое может сделать и B. Протокол предполагает, что A и B доверяют друг другу. Итак, симметричным криптосистемам присущи следующие проблемы :

Распределение ключей должно проводиться в секрете. Ключи столь же важны, как и все сообщения, зашифрованные этими ключами, так как знание ключа позволяет раскрыть все сообщения . Для распространенных систем шифрования задача распределения ключей - серьезнейшая задача . Часто курьеры лично доставляют ключи по назначению.

  • Если ключ скомпрометирован (украден, разгадан, выпытан, получен за взятку и т.д.), то Е сможет расшифровать все сообщения, зашифрованные этим ключом. Он сможет также выступить в качестве одной из сторон и создавать ложные сообщения, дурача другую сторону .
  • В предположении, что каждая пара пользователей сети использует отдельный ключ, общее число ключей быстро возрастает с ростом числа пользователей. Сеть из п пользователей требует n{n - l)/2 ключей. На пример, для общения 10 пользователей между собой нужно 45 различных ключей, для 100 пользователей потребуется 4950 ключей. Решение проблемы - в уменьшении числа пользователей, но это не всегда возможно.

Передача информации с использованием криптографии с открытыми ключами


Взгляните на симметричный алгоритм как на сейф. Ключ является комбинацией. Знающий комбинацию человек может открыть сейф, положить в него документ и снова закрыть. Кто-то другой при помощи той же комбинации может открыть сейф и забрать документ. Тем, кто не знает комбинации, придется научиться взламывать сейфы.

В 1976 году Уитфилд Диффи и Мартин Хеллман навсегда изменили эту парадигму криптографии. Они описали криптографию с открытыми ключами, используя два различных ключа - один открытый и один закрытый. Определение закрытого ключа по открытому требует огромных вычислительных затрат. Кто угодно, используя открытый ключ может зашифровать сообщение, но не расшифровать его. Расшифровать сообщение может только владелец закрытого ключа. Это похоже на превращение криптографического сейфа в почтовый ящик. Шифрование с открытым ключом аналогично опусканию письма в почтовый ящик, любой может сделать это, опустив письмо в прорезь почтового ящика. Дешифрирование с закрытым ключом напоминает извлечение почты из почтового ящика. Обычно это гораздо сложнее - вам может понадобиться сварочный агрегат . Однако, если вы знаете секрет (у вас есть ключ от почтового ящика), вы без труда достанете вашу почту.

Математической основой процесса являются однонаправленные хэш-функции с люком. Шифрование выполняется в прямом направлении. Указания по шифрованию открыты, каждый может зашифровать сообщение. Дешифрирование выполняется в обратном направлении. Оно настолько трудоемко, что, не зная секрета, даже на компьютерах Cray за тысячи (и миллионы) лет невозможно расшифровать cooбщение. Секретом, или люком, и служит закрытый ключ, он делает дешифрирование таким же простым, как и шифрование. Вот как, используя криптографию с открытыми ключами, A может послать сообщение B:

  1. A и B согласовывают криптосистему с открытыми ключами.
  2. B посылает А свой открытый ключ.
  3. A шифрует свое сообщение и отправляет его B.
  4. B расшифровывает сообщение A с помощью своего закрытого ключа.

Обратите внимание, что криптография с открытыми ключами устраняет проблему распределения ключей, присущую симметричным криптосистемам. Раньше A и B должны были тайно договориться о ключе. A мог выбрать любой ключ, но ему нужно было передать его B. Он мог сделать это заранее, но это требует от нее определенной предусмотрительности. Он мог бы послать ключ с секретным курьером, но для этого нужно время. Криптография с открытыми ключами все упрощает. A может отправить B секретное сообщение без каких-либо предварительных действий. У Е, подслушивающему абсолютно все, есть открытый ключ B и сообщение, зашифрованное этим ключом, но она не сможет получить ни закрытый ключ B, ни текст сообщения.

Обычно целая сеть пользователей согласовывает используемую криптосистему. У каждого из них есть открытый и закрытый ключ, открытые ключи помещаются в общедоступной базе данных . Теперь протокол выглядит еще проще:

  1. A извлекает открытый ключ B из базы данных.
  2. A шифрует свое сообщение с помощью открытого ключа B и посылает его B.
  3. B расшифровывает сообщение А с помощью своего закрытого ключа.

В первом протоколе B должен был послать А ее открытый ключ прежде, чем она могла отправить ему сообщение. Второй протокол больше похож на обычную почту. B не участвует в протоколе до тех пор, пока он не начнет читать сообщение. Достаточно хорошим примером использования системы с открытым ключом является популярная система RSA.

Цифровые подписи

Рукописные подписи издавна используются как доказательство авторства документа или, по крайней мере, согласия с ним. Что же так притягательно в подписи?

  • Подпись достоверна. Она убеждает получателя документа в том, что подписавший сознательно подписал документ.
  • Подпись неподдельна. Она доказывает, что именно подписавший, и никто иной, сознательно подписал документ.
  • Подпись не может быть использована повторно. Она является частью документа, жулик не сможет перенести подпись на другой документ.
  • Подписанный документ нельзя изменить. После того, как документ подписан, его невозможно изменить.
  • От подписи не возможно отречься. Подпись и документ материальны. Подписавший не сможет впоследствии утверждать, что он не подписывал документ.

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

Хотелось бы реализовать что-нибудь подобное и на компьютерах, но есть ряд проблем . Во первых, компьютерные файлы скопировать не просто, а очень просто. Даже если подпись человека трудно подделать (например, графическое изображение рукописной подписи), можно легко вырезать правильную подпись из одного документа и вставить в другой. Простое наличие такой подписи ничего не означает. Во вторых, компьютерные файлы очень легко можно изменить после того, как они подписаны, не оставляя ни малейшего следа изменения .

Подпись документа с помощью симметричных криптосистем и посредника

A хочет подписать цифровое сообщение и отправить его B. Она может это сделать с помощью C и симметричной криптосистемы.

С -посредник, которому доверяют. Он может связываться и с А, и с B (и со всеми другими желающими подписывать цифровые документы). Он выдает секретный ключ, КА,- А и другой секретный ключ, Кв, - B. Эти ключи определяются задолго до начала действия протокола и могут быть использованы многократно для многих подписей.

  1. A шифрует свое сообщение B ключом КА и посылает его С.
  2. С, зная ключ КА, расшифровывает сообщение.
  3. С добавляет к расшифрованному сообщению утверждение, что он получил это сообщение от А, и шифрует это новое сообщение ключом Кв.
  4. С посылает новое сообщение B.
  5. B расшифровывает сообщение ключом Кв. Он может прочитать и сообщение А и подтверждение С, что сообщение отправлено именно A.

Откуда С узнает, что сообщение пришло именно от A, а не от какого-то самозванца ? Он делает этот вывод из шифрования сообщения.

Также ли это хорошо, как подпись на бумаге? Посмотрим на требуемые свойства:

  • Эта подпись достоверна. С - это заслуживающий доверия посредник, и С знает, что сообщение получено от A. Подтверждение С служит доказательством для B.
  • Эта подпись неподдельна. Только A (и С, но ему все верят) знает КА, поэтому только A могла послать С сообщение, зашифрованное ключом КА. Если кто-нибудь попытается выдать себя за А, С сразу заметит это на этапе (2) и не заверит подлинность.
  • Эту подпись нельзя использовать повторно. Если B попытается взять подтверждение С и присоединить его к другому сообщению, A закричит "Караул!" Посредник (С или кто-то совсем другой, имеющий доступ к той же информации) попросит B предъявить его сообщение и шифрованное сообщение A. Затем посредник зашифрует сообщение ключом КА и увидит, что оно не соответствует шифрованному сообщению, переданному B. B, конечно же, не сможет создать правильное шифрованное сообщение, потому что он не знает ключа КА.
  • Подписанный документ нельзя изменить. Если B попытается, получив документ, изменить его, С обнаружит мошенничество уже описанным способом.
  • От подписи невозможно отказаться. Если впоследствии A заявит, что он никогда не посылал сообщение, то подтверждение С докажет обратное.

Если B захочет показать D документ, подписанный А, он не сможет раскрыть ей свой секретный ключ. Ему придется снова обратиться к С:

  1. B берет сообщение и утверждение С, что сообщение получено от A, шифрует их ключом Кв и посылает обратно С.
  2. С расшифровывает полученный пакет с помощью ключа Кв.
  3. С проверяет свою базу данных и подтверждает, что отправителем оригинального сообщения была A.
  4. С шифрует полученный от B пакет ключом Kc, который он выделил для К, и посылает К шифрованный пакет.
  5. С расшифровывает полученный пакет с помощью ключа Kc. Теперь он может прочитать и сообщение, и подтверждение С, что сообщение отправленое А.

Подпись документа с помощью криптографии с открытыми ключами

Существуют алгоритмы с открытыми ключами, которые можно использовать для цифровых подписей. В некоторых алгоритмах - примером является RSA - для шифрования может быть использован или открытый, или закрытый ключ. Зашифруйте документ своим закрытым ключом, и вы получите надежную цифровую подпись. В других случаях - примером является DSA - для цифровых подписей используется отдельный алгоритм, который невозможно использовать для шифрования . Эта идея впервые была изобретена Диффи и Хеллманом и в дальнейшем была расширена и углублена в других работах. Основной протокол прост:

  1. A шифрует документ своим закрытым ключом, таким образом подписывая его.
  2. A посылает подписанный документ B.
  3. B расшифровывает документ, используя открытый ключ A, таким образом проверяя подпись.

Этот протокол гораздо лучше предыдущего. С не нужен ни для подписи документов, ни для ее проверки. (Он нужен для подтверждения, что открытый ключ принадлежит именно А.) С не нужен сторонам даже для разрешения споров: Если B не смог осуществить этап (3), то он знает, что подпись неправильна. Такая подпись соответствует всем требованиям:

üЭта подпись достоверна. Когда B расшифровывает сообщение с помощью открытого ключа A, он знает что она подписала это сообщение.

üЭта подпись неподдельна. Только A знает свой закрытый ключ.

üЭту подпись нельзя использовать повторно. Подпись является функцией документа и не может быть перенесена на другой документ.

üПодписанный документ нельзя изменить. После любого изменения документа подпись не сможет больше подтверждаться открытым ключом A.

üОт подписи невозможно отказаться. B не требуется помощь A при проверке его подписи.

Подпись документа и метки времени

На самом деле, при определенных условиях B сможет смошенничать. Он может повторно использовать документ и подпись совместно. Это не имеет значения, если A подписал контракт (одной копией подписанного контракта больше, одной меньше-пустяки, дело обычное), но что если A поставила цифровую подпись под чеком?

Предположим, что A послал B подписанный чек на $100. B отнес чек в банк, который проверил подпись и перевел деньги с одного счета на другой. B, выступающий в роли жулика, сохранил копию электронного чека. На следующей неделе он снова отнес его в этот или другой банк. Банк подтвердил подпись и перевел деньги с одного счета на другой. Если A не проверяет свою чековую книжку, B сможет проделывать это годами.

Поэтому в цифровые подписи часто включают метки времени. Дата и время подписания документа добавляются к документу и подписываются вместе со всем содержанием сообщения . Банк сохраняет эту метку времени в базе данных. Теперь, если B попытается получить наличные по чеку A во второй раз, банк проверит метку времени по своей базе данных. Так как банк уже оплатил чек A с той же меткой времени, то будет вызвана охрана….

Стоп, стоп, стоп…. Кажется я немного перебрал и перепутал порядок вещей… Протоколы это хорошо, но стоило бы разобраться с терминологией, или, как принято говорить "Договоримся о терминах"

Продолжаю…

Отправитель, получатель и злоумышленник

Предположим, что отправитель хочет послать сообщение получателю. Более того, этот отправитель хочет послать свое сообщение безопасно: он хочет быть уверен, что перехвативший это сообщение (злоумышленник) не сможет его прочесть.

Сообщения и шифрование

Само сообщение называется открытым текстом . Изменение вида сообщения так, чтобы спрятать его суть называется шифрованием. Шифрованное сообщение называется шифротекстом (шифрограммой). Процесс преобразования шифротекста в открытый текст называется дешифрированием.

Или, изображая графически

Обозначим открытый текст как М (от message, сообщение). Это может быть поток битов, текстовый файл, битовое изображение, оцифрованный звук, цифровое видеоизображение... да что угодно. Для компьютера M - это просто двоичные данные. Открытый текст может быть создан для хранения или передачи. В любом случае, M - это сообщение, которое должно быть зашифровано.



Обозначим шифротекст как С (от ciphertexеt). Это тоже двоичные данные, иногда того же размера, что и M, иногда больше. (Если шифрование сопровождается сжатием, С может быть меньше чем M. Однако, само шифрование не обеспечивает сжатие информации.) Функция шифрования E действует на M, создавая С. Также обозначим процесс дешифрования через D (decrypt, дешифрование).Или, в математической записи:


E(M) = С


В обратном процессе функция дешифрирования D действует на С, восстанавливая M:

D(C) = M


Поскольку смыслом шифрования и последующего дешифрирования сообщения является восстановление пеpвоначального открытого текста, должно выполняться следующее равенство :


D(E(M)) = M


Кроме обеспечения конфиденциальности криптография часто используется для других функций Проверка подлинности. Получатель сообщения может проверить его источник, злоумышленник не сможет замаскироваться под кого-либо.

Целостность. Получатель сообщения может проверить, не было ли сообщение изменено в процесседоставки, злоумышленник не сможет подменить правильное сообщение ложным.

Неотрицание авторства. Отправитель не сможет ложно отрицать отправку сообщения.


Алгоритмы и ключи


Криптографический алгоритм, также называемый шифром, представляет собой математическую функцию, используемую для шифрования и дешифрирования. (Обычно это две связанные функции: одна для шифрования, а другая для дешифрирования.)

Если безопасность алгоритма основана на сохранении самого алгоритма в тайне, это ограниченный алгоритм. Ограниченные алгоритмы представляют только исторический интерес, но они совершенно не соответствуют сегодняшним стандартам. Большая или изменяющаяся группа пользователей не может использовать такие алгоритмы, так как всякий раз, когда пользователь покидает группу, ее члены должны переходить на другой алгоритм. Алгоритм должен быть заменен и, если кто-нибудь извне случайно узнает секрет.

Что еще хуже, ограниченные алгоритмы не допускают качественного контроля или стандартизации. У каждой группы пользователей должен быть свой уникальный алгоритм. Такие группы не могут использовать открытые аппаратные или программные продукты - злоумышленник может купить такой же продукт и раскрыть алгоритм. Им приходится разрабатывать и реализовывать собственные алгоритмы. Если в группе нет хорошего криптографа, то как ее члены проверят, что они пользуются безопасным алгоритмом?

Несмотря на эти основные недостатки ограниченные алгоритмы необычайно популярны для приложений с низким уровнем безопасности. Пользователи либо не понимают проблем, связанных с безопасностью своих систем, либо не заботятся о них, плюс ко всему такие системы порой стоят на порядок дороже, но как известно скупой платит дважды.

Современная криптография решает эти проблемы с помощью ключа К (key). Такой ключ может быть любым значением, выбранным из большого множества. Множество возможных ключей называют пространством ключей. Теперь эти функции выглядят как(рис №4) :


ЕК(М)=С

DK(C)=M


При этом выполняется следующее равенство:


DK(EK(M))=M


Для некоторых алгоритмов при шифровании и дешифрировании используются различные ключи (рис № 3)To есть ключ шифрования, К1, отличается от соответствующего ключа дешифрирования, К2. В этом случае:

ЕК1/М)=С DK2(C)=M

ВКгк(М))=М


Безопасность этих алгоритмов полностью основана на ключах, а не на деталях алгоритмов. Это значит, что алгоритм может быть опубликован и проанализирован. Продукты, использующие этот алгоритм, могут широко тиражироваться. Не имеет значения, что злоумышленнику известен ваш алгоритм, если ему не известен конкретный ключ, то он не сможет прочесть ваши сообщения.

Криптосистема представляет собой алгоритм плюс все возможные открытые тексты, шифротексты и ключи .



Или, в случае использования 2-х ключей:



Симметричные алгоритмы

Существует два основных типа алгоритмов, основанных на ключах: симметричные и с открытым ключом. Симметричные алгоритмы, иногда называемые условными алгоритмами, представляют собой алгоритмы, в которых ключ шифрования может быть рассчитан по ключу дешифрирования и наоборот. В большинстве симметричных алгоритмов кличи шифрования и дешифрирования одни и те же. Эти алгоритмы, также называемые алгоритмами с секретным ключом или алгоритмами с одним ключом, требуют, чтобы отправитель и получатель согласовали используемый ключ перед началом безопасной передачи сообщений. Безопасность симметричного алгоритма определяется ключом, раскрытие ключа означает, что кто угодно сможет шифровать и дешифрирoвать сообщения. Пока передаваемые сообщения должны быть тайными, ключ должен храниться в секрете. Шифрование и дешифрирование с использованием симметричного алгоритма обозначается как:


ЕК(М)=С DK(C)=M


Симметричные алгоритмы делятся на две категории. Одни алгоритмы обрабатывают открытый текст побитно (иногда побайтно), они называются потоковыми алгоритмами или потоковыми шифрами. Другие работаю с группами битов открытого текста. Группы битов называются блоками, а алгоритмы - блочными алгоритмами или блочными шифрами. Для алгоритмов, используемых в компьютерных модемах, типичный размер блока составляет 64 бита - достаточно большое значение, чтобы помешать анализу, и достаточно небольшое и удобное для работы.


Алгоритмы с открытым ключом


Алгоритмы с открытым ключом (называемые асимметричными алгоритмами) разработаны таким образом, что ключ, используемый для шифрования, отличается от ключа дешифрирования . Более того, ключ дешифрирования не может быть (по крайней мере в течение разумного интервала времени) рассчитан по ключу шифрования. Алгоритмы называются "с открытым ключом", потому что ключ шифрования может быть открытым: кто угодно может использовать ключ шифрования для шифрования сообщения, но только конкретный чeловек с соответствующим ключом дешифрирования может расшифровать сообщение. В этих системах ключ шифрования часто называется открытым ключом, а ключ дешифрирования - закрытым. Закрытый ключ иногда называется секретным ключом, но чтобы не было путаницы с симметричными алгоритмами. Шифрование с открытым ключом К обозначается как:


ЕК(М)=С


Хотя открытый и закрытый ключи различны, дешифрирование с соответствующим закрытым ключом обoзначается как:


Dk (C)=M


Иногда сообщения шифруются закрытым ключом, а дешифрируются открытым, что используется для цифровой подписи .Несмотря на возможную путаницу эти операции, соответственно, обозначаются как:


ЕК(М)=С DK(C)=M


Криптоанализ

Хотя я и не хотел писать о вскрытии, но это почти то же самое как и не объяснить в музыкальной школе ребенку разницу между скрипичным и басовым ключом .Смысл криптографии - в сохранении открытого текста (или ключа, или и того, и другого) в тайне от злоумышленников. Предполагается, что злоумышленники полностью контролируют линии связи между отправителем и получателем .

Криптоанализ - это наука получения открытого текста, не имея ключа. Успешно проведенный криптоанализ может раскрыть открытый текст или ключ. Он также может обнаружить слабые места в криптосистемах, что в конце концов приведет к предыдущему результату.

Попытка криптоанализа называется вскрытием. Основное предположение криптоанализа, впервые сформулированное в девятнадцатом веке Датчманом А. Керкхофсом (Dutchman A. Kerckhoffs), состоит в том, что безопасность полностью определяется ключом. Керкхофс предполагает, что у криптоаналитика есть полное описание алгоритма и его реализации. (Конечно же, у ЦРУ не в обычае сообщать Моссад о своих криптoграфических алгоритмах, но Моссад возможно все равно добудет их .) Хотя в реальном мире криптоаналитики не всегда обладают подробной информацией, такое предположение является хорошей рабочей гипотезой . Если противник не сможет взломать алгоритм, даже зная, как он работает, то тем более враг не сможет вскрыть алгоритм без этого знания.

Существует четыре основных типа криптоаналитического вскрытия . Для каждого из них, конечно, предполагается, что криптоаналитик обладает всей полнотой знания об используемом алгоритме шифрования :

.Вскрытие с использованием только шифротекста У криптоаналитика есть шифротексты нескол ьких сообщений, зашифрованных одним и тем же алгоритмом шифрования . Задача криптоаналитика состоит в раскрытии открытого текста как можно большего числа сообщений или, что лучше, получeнии ключа (ключей), использованного для шифрования сообщений, для дешифрировании других сoобщений, зашифрованных теми же ключами.

.Вскрытие с использованием открытого текста

У криптоаналитика есть доступ не только к шифротекстам нескольких сообщений, но и к открытому тексту этих сообщений . Его задача состоит в получении ключа (или ключей), использованного для шифрования сообщений, для дешифрировании дрyгих сообщений, зашифрованных тем же ключом (ключами).

.Вскрытие с использованием выбранного открытого текста

У криптоаналитика не только есть доступ к шифротекстам и открытым текстам нескольких сообщений, но и возможность выбирать открытый текст для шифрования. Это предоставляет больше вариантов чем вскрытие с использованием открытого текста, так как криптоаналитик может выбирать шифруемые блоки открытого текста, что может дать больше информации о ключе. Его задача состоит в получении ключа (или ключей), использованного для шифрования сообщений, или алгоритма, позволяющего дешифрировать новые сoобщения, зашифрованные тем же ключом (или ключами).

.Адаптивное вскрытие с использованием открытого текста

Это частный случай вскрытия с использованием выбранного открытого текста. Криптоаналитик не только может выбирать шифруемый текст, но также может строить свой последующий выбор на базе полученных результатовшифрования. При вскрытии с использованием выбранного открытого текста криптоаналитик мог вы брать для шифрования только один большой блок открытого текста, при адаптивном вскрытии с иcпользованием выбранного открытого текста он может выбрать меньший блок открытого текста, затем выбрать следующий блок, используя результаты первого выбора и так далее .

. Вскрытие с использованием выбранного шифротекста

Криптоаналитик может выбрать различные шифротексты для дешифрирования и имеет доступ к дешифрированным открытым текстам . На пример, у криптоаналитика есть доступ к "черному ящику", который выполняет автоматическое дeшифрирование. Его задача состоит в получении ключа.

Такой тип вскрытия обычно применим к алгоритмам с открытым ключом/ Вскрытие с использование выбранного шифротекста иногда также эффективно против симметричных алгоритмов. (Иногда вскрытие с использованием выбранного открытого текста и вскрытие с использованием выбранного шифротекста вместе называют вскрытием с использованием выбранного текста.)

. Вскрытие с использованием выбранного ключа

Такой тип вскрытия означает не то, что криптоаналитик может выбирать ключ, а что у него есть некоторая информация о связи между различными ключами

. Бандитский криптоанализ.

Криптоаналитик угрожает, шантажирует или пытает кого-нибудь, пока не получит ключ. Взяточничество иногда называется вскрытием с покупкой ключа Это оченьмощные способы вскрытия, часто являющиеся наилучшим путем взломать алгоритм (и порой самым вероятным) .


Безопасность алгоритмов


Различные алгоритмы предоставляют различные степени безопасности в зависимости от того, насколько трудно взломать алгоритм. Если стоимость взлома алгоритма выше, чем стоимость зашифрованных данных, вы, скорее всего, в безопасности. Если время взлома алгоритма больше, чем время, в течение которого зашифрованные данные должны сохраняться в секрете, то вы также, скорее всего, в безопасности . Если объем данных, зашифрованных одним ключом, меньше, чем объем данных, необходимый для взлома алгоритма, и тогда вы, скорее всего, в безопасности."Cкорее всего", потому что существует вероятность новых прорывов в криптоанализе. С другой стороны, значимость большинства данных падает со временем. Важно, чтобы значимость данных всегда остaвалась меньше, чем стоимость взлома системы безопасности, защищающей данные .

Типы вскрытия алгоритмов по следующим категориям, приведенным в пoрядке убывания значимости :

Полное вскрытие. Криптоаналитик получил ключ, К, такой, что DK(C) = Р.

Глобальная дедукция. Криптоаналитик получил альтернативный алгоритм, А, эквивалентный DK(C) без знания К.

Местная (или локальная)дедукция. Криптоаналитик получил открытый текст для перехваченного шифротекста.

Информационная дедукция. Криптоаналитик получил некоторую информацию о ключе или открытом тексте. Такой информацией могут быть несколько бит ключа, сведения о форме открытого текста и так далее.

Алгоритм является безусловно безопасным, если, независимо от объема шифротекстов у криптоаналитика, информации для получения открытого текста недостаточно. По сути, только шифрование одноразовыми блокнотами невозможно вскрыть при бесконечных ресурсах. Все остальные криптосистемы подвержены вскрытию с использованием только шифротекста простым перебором возможных ключей и провеpкой осмысленности полученного открытого текста. Это называется вскрытием грубой силой.

Криптография больше интересуется криптосистемами, которые тяжело взломать вычислительным способом. Алгоритм считается вычислительно безопасным (или, как иногда называют, сильным), если он не может быть взломан с использованием доступных ресурсов сейчас или в будущем. Термин "доступные ресурсы" является достаточно расплывчатым. Сложность вскрытия можно измерить различными способами:

Сложность данных. Объем данных, используемых на входе операции вскрытия.

Сложность обработки. Время, нужное для проведения вскрытия. Часто называется коэффициентом работы.

Требования к памяти. Объем памяти, необходимый для вскрытия.

В качестве эмпирического метода сложность вскрытия определяется по максимальному из этих трех коэффициентов. Ряд операций вскрытия предполагают взаимосвязь коэффициентов: более быстрое вскрытие возможно за счет увеличения требований к памяти.

Сложность выражается порядком величины. Если сложность обработки для данного алгоритма составляет 2128, то 2128 операций требуется для вскрытия алгоритма. (Эти операции могут быть сложными и длительными.) Так, если предполагается, что ваши вычислительные мощности способны выполнять миллион операций в сeкунду, и вы используете для решения задачи миллион параллельных процессоров, получение ключа займет у вас свыше 1019 лет, что в миллиард раз превышает время существования вселенной. Однако неутешительно...Но! В то время, как сложность вскрытия остается постоянной (пока какой-нибудь криптоаналитик не придумает лучшего способа вскрытия), мощь компьютеров растет. За последние полвека вычислительные мощности фeноменально выросли, и нет никаких причин подозревать, что эта тенденция не будет продолжена. Многие криптографические взломы пригодны для параллельных компьютеров: задача разбивается на миллиарды маленьких кусочков, решение которых не требует межпроцессорного взаимодействия. Объявление алгоритма безопасным просто потому, что его нелегко взломать, используя современную технику, в лучшем случае ненадежно. Хорoшие криптосистемы проектируются устойчивыми к взлому с учетом развития вычислительных средств на много лет вперед.

Ну, я так понимаю что настало самое время привести небольшой пример вскрятия шифра. Нет я не могу да и врядли кто сможет, на листе вкрыть DES,AES, или RSA. Мой пример будет прости, но в то же время нагляден.


Вскрытие шифра простой замены


Разберем пример. Итак, допустим, на доске объявлений, появилась следующая надпись:


ТБПО ЩИЧЧЖ ЛНИЬЕЭФЭЕЭВЬ ЭКМНИО ИЩЩСКИЬОЭСФБИТЬЛИЬШ ТБПОЧЩЬП ЛНОЭЧЖ Ь ЧЛЭПЛКПЕПООЭ

ЛЭНЛКИВИЫП ФЭБСТПООЖП ЬН ЩИЧЧЖ ЧЧСУЖ

Несомненно, что это шифр. Каков же его тип? Это не может быть шифр перестановки, так как в шифровке четко проглядываются слова с регулярными окончаниями чж, иыи, оэ. Частоты встречи различных знаков шифровки явно неодинаковы. Знаки Ч, И, Э встречаются раз по десять, тогда как У, Ю и М лишь по одному разу, что не бывает в многоалфавитных шифрах, имеющих близкие вероятности знаков.Естественно предположить, что применен шифр простой замены. С чего следует начать расшифровывание? Несомненно, с установления отправителя и получателя сообщения. Вспомним рассуждения Холмса из "Пляшущих человечков", который сразу же отождествил смешную надпись с шифровкой. Что в этой надписи могло напугать героиню, угроза? Представим, что она прочла текст: "Готовься к смерти". Не правда ли, такое неприятное сообщение слишком абстрактно, чтобы заставить ужаснуться спокойного волевого человека: кто должен готовиться и к чьей смерти? Поэтому решил Холмс, героиню напугало собственное имя и начал расшифровку отождествлением слова "Илей" с первыми четырьмя человечками. Зачастую, кроме имени получателя сообщения содержат еще и имя отправителя, как это принято в телеграммах: "Приезжаю шестого. Мама." У нашей шифровки была приписка: "Граждане, ознакомившиеся, запомнившие и исполнившие, принимаются ежедневно и без ограничений. Местком." Из нее ясен отправитель - местком. Поэтому шифрованный текст может не содержать его названия. Получатель все же должен быть доуточнен, как обращение: "всем садоводам..." или "члены кружка...". Однако это - слишком легкий путь. и предположим, что не удалось конкретизировать получателя, чтобы, используя его имя, вскрыть шифр.

Предположение 1. Внимательно просматривая шифровку, можно обнаружить интересное удвоение знака Ч в конце последнего слова и начале последнего: щиччх ЧЧСУХ. Кажется, что этот знак весьма похож на употребление буквы С в русском тексте, как МАССА ССЫЛОК или ЛАССО ССУЧИЛ. Например, для буквы В не удается подобрать хороший пример, чтобы она удваивалась в конце слов, а для буквы Н - в начале. Отметим, что удвоение С в конце характерно для заимствованных существительных, где перед ним стоит чаще всего буква А. Значит, буква шифровки Ч соответствует в тексте С, а И соответствует русской букве А.

Предположение 2. Другое удвоение, знака о, встречается только в конце слов и типично для русской буквы Н. Поэтому сочетания знаков на концах слов шифровки ОЭ и ооэ, скорее всего отвечают русским окончаниям в сообщении НО и ННО. Если это так, то последнее слово шифровки ЧЧСУЖ, начинающееся с СС и состоящее из пяти букв может быть лишь одним из двух слов - ССУДЕ или ССУДЫ, что легко проверить по словарю. Другие варианты прочтения ССУДА, ССОРА и тому подобные отпадают, так как буквы А иО уже разгаданы.

Предположение 3. Знак шифровки ж, стоящий в конце слова ЧЧСУЖ встречается довольно редко, если учесть, что слово щиччж повторяется, а одинаковое окончание последнего и предпоследнего слов представляет собой обычное согласование слов в предложении. Это означает, что знаку ж скорее отвечает буква Ы, чем более часто встречаемая в русских текстах Е, а последнее слово - ССУДЫ. Окончание сообщения ?АССЫ ССУДЫ теперь нетрудно отгадать как КАССЫ ССУДЫ, что весьма близко к осмысленному тексту. Из отгадан- ных букв пятое слово шифровки складывается как АККУ?А?НО, что несомненно означает АККУРАТНО, а седьмое слово ??НОСЫ из контекста можно понять как ВЗНОСЫ. Итак, отгадывание идет вроде бы успешно, что подтверждается частичной расшифровкой:


???Н КАССЫ ВЗА??0?0?0?? 0??ЗАН АККУРАТ-НО У??А??ВАТ? ???НСК?? ВЗНОСЫ ?СВО?ВР???ННО ВОЗВРА?АТ? ?0?У??ННЫ? ?3КАССЫ ССУДЫ

Теперь дальнейшая расшифровка не представляет особого труда и выполняется быстро, угадыванием отдельных слов и подстановкой выясненных букв в шифровку. В итоге получаем сообщение:


ЧЛЕН КАССЫ ВЗАИМОПОМОЩИ ОБЯЗАНАККУРАТНО УПЛАЧИВАТЬ ЧЛЕНСКИЕВЗНОСЫ И СВОЕВРЕМЕННО ВОЗВРАЩАТЬПОЛУЧЕННЫЕ ИЗ КАССЫ ССУДЫ


Приведенный пример расшифровки не претендует на изящество, поскольку представляет собой реальный протокол рассуждений криптоаналитика без тупиковых вариантов, и показывает изнутри процесс вскрытия шифра простой замены. Возникает вопрос: насколько можно доверять правильности вскрытия этого шифра простой замены?

Лучше всего на него ответить словами Архимеда из послания к Эратосфену: "Хотя это всем вышеприведенным рассуждением и не доказано, но все же производит впечатление, что окончательный вывод верен".По ряду свидетельств, опытные криптоаналитики читают такие шифровки "с листа", потратив на это минуту-другую, что свидетельствует о профессиональном видении структуры текста в кажущейся мешанине букв. В этом они сильно превосходят компьютер, которая удовлетворительно читает шифр простой замены лишь при достаточно большой длине сообщения больше сотни символов. Однако и здесь компьютер может серьезно помочь в раскалывании шифра, например, разделив буквы на гласные и согласные. Так как гласные и согласные имеют тенденцию чередоваться, то можно по матрице чередований символов разделить их на эти классы (для этого на компьютере криптоаналитики традиционно используют так называемое сингулярное разложение матрицы переходных вероятностей.). Кроме того, можно программно оценить вероятности принадлежности символов шифра разным буквам выписать их столбцами по убыванию вероятности, что даст другую технику вскрытия этого шифра. Применение распознавания, основанного на оценке лишь вероятностей отдельных символов в тексте и биграмм, за 10 этапов обучения дало по приведенной шифровке следующий текст:


ЧРЕН КАССЫ ВЗАИМОПОМОБИ ОДЯЭАН АККУЛАТНОУПРАЧИВАТЬ ЧРЕНСКИЕ ВЫНОСЫ И СВОЕВЛЕМЕННОВОЗВЛАБАТЬ ПОРУЧЕННЫЕ ИЗ КАССЫ ССУШ


Получился довольно хорошо читаемый текст, хотя и за время, превысившее ручную расшифровку.

После корректировки написания по словарю русского языка, он приобрел такой вид:


ЧЛЕН КАССЫ ВЗАИМОПОМОЩИ ОБЯЗАН АККУРАТНОУПРОЧИВАТЬ ЧЛЕНСКИЕ ВЫНОСЫ И СВОЕВРЕМЕННОВОЗВРАЩАТЬ ПОРУЧЕННЫЕ ИЗ КАССЫ ССУДЫ


Машинное вскрытие шифров простой замены вряд ли в близком будущем потеряет свою актуальность. Криптоаналитики широко им пользуются, поскольку атаки на сложные шифры заканчиваются обычно вскрытием шифра простой замены.

Ну и в догонку


Взлом многоалфавитных шифров


Многоалфавитные шифры вскрывается довольно легко, если учесть следующее обстоятельство: так как цифр всего 10, то имеется лишь 10 вариантов прочтения каждой буквы. Выпишем их столбцами так, что одной строке соответствуют буквы одного значения ключа. Номер варианта будет определяться цифрой ключа от 0 до 9. При этом получим таблицу, правильно выбрав по одной букве из каждой колонки которой можно получить исходный текст:


Ключ???????????????????вариант 0ФПЖИСЬИОССАХИЛФИУССвариант 1УОЕЗРЫЗНРР ФЗКУЗТРРвариант 2ТНДЖПЪЖМППЯУЖЙТЖСППвариант 3СМГЕОЩЕЛООЮТЕИСЕРООвариант 4РЛВДНШДКННЭСДЗРДПННвариант 5ПКБГМЧГЙММЬРГЖПГОММвариант 6ОЙАВЛЦВИЛЛЫПВЕОВНЛЛвариант 7НИ БКХБЗККЪОБДНБМККвариант 8МЗЯАЙФАЖЙЙЩНАГМАЛЙЙвариант 9ЛЖЮ ИУ ЕИИШМ ВЛ КИИсообщение???????????????????

Предположение 1. Если прочесть исходный текст напрямую не удалось, то попробуем немного порасуждать. Самый частый символ текста - пробел, а разбиение фразы на слова порой может оказать большую помощь в расшифровке, как это уже было в случае вскрытия шифра решетки. Так как длина шифровки равна 19 символам, то она состоит из двух или трех слов, разделенных пробелами. Хорошее положение для пробела дает лишь вариант 1, а другие варианты, 7 и 9 или их сочетания маловероятны. Поэтому будем считать, что текст шифровки разбивается на два слова: ФПХИСЫЮСС ХИЛФИУСС. Из этого следует, что в 11 позиции текста стоит пробел и в той же позиции ключа находится цифра 1.

Предположение 2. У выделенных слов шифровки одинаковое окончание ее, и, весьма вероятно, что период ключа делит 9 - длину второго слова вместе с пробелом. Будем считать, что в этом случае одинаковые окончания слов (Одинаковые окончания часто появляются из-за согласования слов в предложениях на русском языке. Это хорошо видно в поговорках: одИН в поле не воИН, наняЛСЯ - продаЛСЯ.) текста попали на одинаковые участки ключа и дали одинаковые символы шифровки. На первый взгляд может показаться, что это слишком маловероятно, чтобы встречаться в практике. Однако таких находок, помогающих расшифровке, всегда бывает предостаточно в сообщениях большой длины и, порой, приходится жалеть скорее об их обилии, чем отсутствии. Если нет никаких идей о длине ключа, не беда - ее можно подобрать вслепую. Итак, есть два выбора для периода ключа: 3 и 9. Попробуем период длины 3:


ключ ?1??1??1??1??1??1??вариант 0Ф ЖИ ЬИ СС ХИ ФИ ССвариант 1УОЕЗРЫЗНРР ФЗКУЗТРРвариант 2Т ДЖ ЪЖ ПП УЖ ТЖ ППвариант 3С ГЕ ЩЕ ОО ТЕ СЕ ООвариант 4Р БД ШД НН СД РД ННвариант 5П БГ ЧГ ММ РГ ПГ ММвариант 6О АВ ЦБ ЛЛ ПВ ОВ ЛЛвариант 7Н Б ХБ КК ОБ НБ ККвариант 8М ЯА ФА ЙЙ НА МА ЙЙвариант 9Л Ю У ИИ МЛ ИИсообщение?о??р??н?? ??к??т??

Таблица существенно поредела, но остается все-таки сложной для непосредственного прочтения (Криптоаналитики вряд ли сочтут прямое чтение ее сложным, так как достаточно перебрать лишь 100 вариантов для двух оставшихся цифр ключа вручную за несколько минут.). Поэтому попробуем подобрать символ ключа, стоящий в первой позиции, перебрав 10 вариантов. Так как ключ длиной 3 циклически повторяется, то этот же символ стоит в 4, 7, 10, 13, 16 и 19 позициях ключа. Вероятность варианта для первой цифры ключа равна произведению вероятностей биграмм, состоящих из символа по этому варианту расшифровки и следующего за ним, уже известного символа. Если Li - буква текста, стоящая на месте i, то вероятность одного из 10 вариантов:р (L1L2) p(L4L5) р(L7L8) p(L10L11) p(L13L14) p(L16L17)

Для вычисления вероятности биграмм воспользуемся таблицей из приложения. Поскольку в ней даны логарифмы вероятностей биграмм, то их достаточно суммировать. В результате для вариантов от 0 до 3 имеем такие численные значения вероятностей:


р(0)=р(ФО)р(ИР)р(ИН)р(С )р(ИК)р(ИТ)=43р(1)=р(УО)р(ЗР)р(ЗН)р(Р )р(ЗК)р(ЗТ)=23р(2)=р(ТО)р(ЖР)р(ЖН)р(П )р(ЖК)р(ЖТ)=27р(3)=р(СО)р(ЕР)р(ЕН)р(О )р(ЕК)р(ЕТ)=50


В результате для первой цифры ключа получается наиболее вероятным 3 вариант расшифровки. Это дает следующую таблицу:


ключ 31?31?31?31?31?31?3вариант 0Ж Ь С Х Ф Свариант 1ОЕ РЫ HP Ф КУ ТРвариант 2Д Ъ П У Т Пвариант 3С ГЕ ЩЕ ОО ТЕ С ООвариант 4в т н с р нвариант 5Б Ч М Р П Мвариант 6А Ц Л П О Лвариант 7Х К О Н Квариант 8Я Ф Й Н М Йвариант 9Ю У И М Л ИсообщениеСО?ЕР?ЕН?0 ?ЕК?РТ?0

Теперь сообщение читается совсем просто. Достаточно выбрать одну из 10 строк с вариантом для 3 цифры ключа. В результате получим ключ и текст сообщения:сообщение: СОВЕРШЕННО СЕКРЕТНОключ: 3143143143143143143

В принципе есть возможность чтения шифра напрямую, анализом таблицы возможных замен, даже если ключ длинный. При достаточно большой длине текста в таблице будут несложно прочитываемые участки. Использование ЭВМ для подключения к криптографической атаке на этот шифр априорных знаний о чередовании русских букв в тексте обычно позволяет без труда читать подобные шифровки.При многоалфавитной замене с длинным ключом использованный для взлома шифра Гронсфельда прием уже не подходит. Однако известно, что шифры русских революционеров цифирная палата легко читала. Как же это удавалось сделать - черная магия? Все гораздо проще. Приведем короткий пример: перехвачена шифровка, вероятным автором которой является Троцкий. Известно также, что аналогичные шифровки делались методом сложной замены и в качестве ключа использовались тексты революционных песен, а иногда стихотворения Пушкина, Лермонтова и Некрасова. Так как отправитель Троцкий, то естественно предположить, что сообщение оканчивается подписью ТРОЦКИЙ с предыдущим пробелом. Подставив ее в шифровку вместо ключа, получим кусок настоящего ключа.


Шифровка ДДЯ Л ЫСЫ ШНМРКЮЮЩДБЬИЬМЫМТАНЭХЦКСообщение????????????????????????? ТРОЦКИЙКлюч ?????????????????????????НАС ЗЛОБ

Не напоминает ли фрагмент НАС ЗЛОБ какой-то известный текст? Не правда ли, очень похоже на слова, переведенной Кржижановским песни польского восстания 1863 года, называемой "Варшавянкой"? Теперь, подставив разгаданный ключ в виде текста песни: ВИХРИ ВРАЖДЕБНЫЕ ВЕЮТ НАД НАМИ ТЕМНЫЕ СИЛЫ НАС ЗЛОБ, можно вскpыть само сообщение:ОБЫВАТЕЛИ СПАЛИ НЕ ЗНАЯ ЧТО МЕНЯЕТСЯ ВЛАСТЬ ТРОЦКИЙ

Такая расшифровка вряд ли заняла бы вместе с составлением сопроводительной записки более часа времени. Ну, а предположим, что отправитель неизвестен? И это не беда, хотя потребует больше времени. Несложно перебрать несколько возможных имен, а в случае неудачи придется подставлять в разные места часто употребляемые слова текста и ключа - ТОВАРИЩ, ВЛАСТЬ, ВОССТАНИЕ. Отгадав одно из двух - текст или ключ, сразу получим второе.Мда неприятная вырисовывается картина однако…. Сразу становится как-то не по себе … получается что вскрывают чаще и проще чем можно подумать…Но унывать не стоит- забегая вперед, скажу что есть нескрываемая системы криптографии- т.н. одноразовый блокнот, и в конце концов вскрыть 512 битовый клоч не так то уж легко и быстро… Но об этом позже….

А теперь настало время самой "труднопроходимой" части. Догадались? Правильно- на сцену выходить её величество-математика, точнее


Теория информации


Современная теория информации впервые была опубликована в 1948 году Клодом Э. Шенноном (Claude Elmwood Shannon).


Энтропия и неопределенность


Теория информации определяет количество информации в сообщении как минимальное количество бит, необходимое для кодирования всех возможных значений сообщения, считая все сообщения равновероятными. Например, для поля дня недели в базе данных достаточно использовать три бита информации, так как вся информация может быть закодирована 3 битами:


1.- Воскресенье

2.- Понедельник

010-Вторник

-Среда

-Четверг

101 -Пятница

-Суббота

- Не используется


Если эта информация была бы представлена соответствующими строками ASCII символов, она заняла бы больше места в памяти, но не содержала бы больше информации. Аналогично, поле базы данных "пол" содеpжит только один бит информации, хотя эта информация может храниться как одно из двух 7-байтовых ASCII строк: "МУЖЧИНА" или "ЖЕНЩИНА".

Формально, количество информации в сообщении M измеряется энтропией сообщения, обозначаемое как H(M). Энтропия сообщения, определяющего пол, составляет! бит, а энтропия сообщения, определяющего день недели, немного меньше, чем 3 бита. В общем случае энтропия сообщения, измеряемая в битах, равна log 2 n, где n - это количество возможных значений. При этом предполагается, что все значения равновероятны.

Энтропия сообщения также является мерой его неопределенности. Это количество битов открытого текста, которое нужно раскрыть в шифротексте сообщения, чтобы узнать весь открытый текст. Например, если блок шифротекста "QHP*5M " означает либо "МУЖЧИНА", либо "ЖЕНЩИНА", то неопределенность сообщения равна 1. Криптоаналитику нужно узнать только один правильно выбранный бит, чтобы раскрыть сообщение.


Норма языка


Для данного языка норма языка равна


r = H(M)/N

где N - это длина сообщения. При больших N норма обычного английского языка принимает различные зонaчения от 1.0 бит/буква до 1.5 бит/буква. Шеннон утверждает, что энтропия зависит от длины текста. Конкретно он показал, что норма для 8-буквенных блоков равна 2.3 бит/буква, но ее значение падает и находится между 1.3 и 1.5 для 16-буквенных блоков. Томас Кавер (Thomas Cover) использовал игровую методику оценки и обнаружил, что энтропия равна 1.3 бит/символ. Я буду использовать значение 1.3 Абсолютная норма языка равна максимальному количеству битов, которое может быть передано каждым символом при условии, что все последовательности символов равновероятны. Если в языке L символов, то абсолютная норма равна:


R = log2 L


Это максимум энтропии отдельных символов.

Для английского языка с 26 буквами абсолютная норма равна log 2 26, или около 4.7 бит/буква. Вас не должно удивлять, что действительная норма английского языка намного меньше, чем абсолютная - естественные языки обладают высокой избыточностью. Избыточность языка, обозначаемая D, определяется как:


D=R-r


Считая, что норма английского языка равна 1.3, избыточность составит 3.4 бит/буква. Это означает, что кaждая английская буква содержит 3.4 бита избыточной информации.

У сообщения ASCII, состоящего только из английских букв, количество информации на каждый байт составляет 1.3 бита. Значит, в каждом байте содержится 6.7 бита избыточной информации, что дает общую избыточность 0.84 бита информации на бит ASCII-текста и энтропию 0.16 бита информации на бит ASCII-текста. To же сообщение, набранное кодом BAUDOT, с 5 битами на символ, имеет избыточность 0.74 бита на бит и энтрoпию 0.26 бита на бит. Пробелы, пунктуация, числа и форматирование изменяют эти результаты.


Расстояние уникальности


Для сообщения длиной n число различных ключей, которые расшифруют шифротекст сообщения в какой-то осмысленный открытый текст на языке оригинального открытого текста (например, английском

Шеннон определил расстояние уникальности, U, называемое также точкой уникальности, как такое приближенное количество шифротекста, для которого сумма реальной информации (энтропия) в соответствующем открытом тексте плюс энтропия ключа шифрования равняется числу используемых битов шифротекста. Затем он показал, что имеет смысл считать, что шифротексты, которые длиннее расстояния уникальности, можно расшифровать только одним осмысленным способом. Шифротексты, которые заметно короче расстояния уникальности, скорее всего, можно расшифровать несколькими способами, каждый из которых может быть правилен, и таким образом обеспечить безопасность, поставив противника перед выбором правильного открытого текста.

Для большинства симметричных криптосистем расстояние уникальности определяется как энтропия криптoсистемы деленная на избыточность языка.


U = H(K)/D


Расстояние уникальности является не точным, а вероятностным значением. Оно позволяет оценить минимальное количество шифротекста, при вскрытии которого грубой силой имеется, вероятно, только один разумный способ дешифрирования. Обычно чем больше расстояние уникальности, тем лучше криптосистема. Для DES с 56-битовым ключом и англоязычного сообщения, записанного символами ASCII, расстояние уникальности приблизительно равно 8.2 символа ASCII или 66 бит. В приведены расстояния уникальности для различных длин ключа.

Расстояние уникальности измеряет не количество криптотекста, нужного для криптоанализа, а количество криптотекста, необходимое для единственности результата криптоанализа. Криптосистема может быть вычиcлительно неуязвима, даже если теоретически ее возможно взломать, используя малое количество шифротекста. Расстояние уникальности пропорционально избыточности. Если избыточность стремится к нулю, даже тривиальный шифр может не поддаться вскрытию с использованием только шифротекста.


Табл. 1. Расстояния уникальности текста ASCII, зашифрованного алгоритмами с различной длиной ключа

Длина ключа (в битах)Расстояние уникальности (в символах)

5^9

8.2

9.4

11.8

18.8

37.6


Шеннон определил криптосистему с бесконечным расстоянием уникальности, как обладающую идеальной тайной. Обратите внимание, что идеальная криптосистема не обязательно является совершенной, хотя совеpшенная криптосистема обязательно будет и идеальной. Если криптосистема обладает идеальной тайной, то даже при успешном криптоанализе останется некоторая неопределенность, является ли восстановленный открытый текст реальным открытым текстом.

Путаница и диффузия


Двумя основными методами маскировки избыточности открытого текста сообщения, согласно Шеннону, служат путаница и диффузия.

Путаница маскирует связь между открытым текстом и шифротекстом. Она затрудняет попытки найти в шифротексте избыточность и статистические закономерности. Простейшим путем создать путаницу является подстановка. В простом подстановочном шифре, например, шифре Цезаря, все одинаковые буквы открытого текста заменяются другими одинаковыми буквами шифротекста. Современные подстановочные шифры являются более сложными: длинный блок открытого текста заменяется блоком шифротекста, и способ замены меняется с каждым битом открытого текста или ключа. Такого типа подстановки обычно недостаточно - сложный алгоритм немецкой Энигмы был взломан в ходе второй мировой войны.

Диффузия рассеивает избыточность открытого текста, распространяя ее по всему шифротексту. Криптоанaлитику потребуется немало времени для поиска избыточности. Простейшим способом создать диффузию является транспозиция (также называемая перестановкой). Простой перестановочный шифр только переставляет буквы открытого текста. Современные шифры также выполняют такую перестановку, но они также используют другие формы диффузии, которые позволяют разбросать части сообщения по всему сообщению.

Потоковые шифры используют только путаницу, хотя ряд схем с обратной связью добавляют диффузию. Блочные алгоритмы применяют и путаницу, и диффузию. Как правило, диффузию саму по себе несложно взломать (хотя шифры с двойной перестановкой оказываются поустойчивее, чем другие некомпьютерные системы, но об этом мы кажется уже говорили).

Арифметика вычетов


Вы все учили математику вычетов в школе.Если Маша сказaла, что она будет дома к 10:00, и опоздала на 13 часов, то когда она придет домой, и на сколько лет отец лишит ее водительских прав? Это арифметика по модулю 12. Двадцать три по модулю 12 равно 11.


(10 + 13) mod 12 = 23 mod 12 = 11 mod 12


Другим способом записать это является утверждение об эквивалентности 23 и 11 по модулю 12:


+13 = ll(modl2)


В основном, а = b (mod n), если а = b + kn для некоторого целого k. Если а неотрицательно и b находится между 0 и и, можно рассматривать b как остаток при делении а на п. Иногда, b называется вычетом а по модулю п. Иногда а называется конгруэнтным b по модулю n (знак тройного равенства, =, обозначает конгруэнтность). Одно и то же можно сказать разными способами.

Множество чисел от 0 до n-\ образует то, что называется полным множеством вычетов по модулю п. Это означает, что для любого целого а, его остаток по модулю n является некоторым числом от 0 до n-1.

Операция a mod n обозначает остаток от а, являющийся некоторым целым числом от 0 до n-1. Эта операция называется приведением по модулю. Например, 5 mod 3 = 2.

Это определение mod может отличаться от принятого в некоторых языках программирования. Например, оператор получения остатка в языке PASCAL иногда возвращает отрицательное число. Он возвращает число между -(и-1) и n-\. В языке С оператор % возвращает остаток от деления первого выражения на второе, оно может быть отрицательным числом, если любой из операндов отрицателен. Для всех алгоритмов, проверяйте, что вы добавляете n к результату операции получения остатка, если она возвращает отрицательное число.

Арифметика остатков очень похожа на обычную арифметику: она коммутативна, ассоциативна и дистрибyтивна. Кроме того, приведение каждого промежуточного результата по модулю n дает тот же результат, как и выполнение всего вычисления с последующим приведением конечного результата по модулю п


(а + b) mod n == ((a mod ri) + (b mod и)) mod n

(а - b) mod n == ((a mod и) - (b mod и)) mod n

(а * b) mod n == ((a mod ri) * (b mod и)) mod n

(а * (b+c)) mod n == (((a*b} mod ri} + ((a*c) mod и)) mod n


Вычисление mod n часто используется в криптографии, так как вычисление дискретных логарифмов и квадратных корней mod n может быть нелегкой проблемой. Арифметика вычетов, к тому же, легче реализуется на компьютерах, поскольку она ограничивает диапазон промежуточных значений и результата. Для k-битовых вычетов n, промежуточные результаты любого сложения, вычитание или умножения будут не длиннее, чем 2 k бит. Поэтому в арифметике вычетов мы можем выполнить возведение в степень без огромных промежуточных peзультатов. Вычисление степени некоторого числа по модулю другого числа,


ax mod n,


представляет собой просто последовательность умножений и делений, но существуют приемы, ускоряющие это действие. Один из таких приемов стремится минимизировать количество умножений по модулю, другой -оптимизировать отдельные умножения по модулю. Так как операции дистрибутивны, быстрее выполнить возвeдение в степень как поток последовательных умножений, каждый раз получая вычеты. Сейчас вы не чувствуете разницы, но она будет заметна при умножении 200-битовых чисел.

Например, если вы хотите вычислить a8 mod n, не выполняйте наивно семь умножений и одно приведение по модулю:


(a * a * a * a * a * a * a * a) mod n

Вместо этого выполните три меньших умножения и три меньших приведения по модулю:


((a2 mod n)2 mod n)2 mod n


Точно также,

a16 mod n =(((a2 mod n)2 mod n)2 mod n)2 mod n


Вычисление ax, где x не является степенью 2, ненамного труднее. Двоичная запись представляет x в виде суммы степеней 2: 25 - это бинарное 11001, поэтому 25 = 24 + 23 + 20. Поэтому

25 mod n = (a*a24) mod n = (a* aS*a16) mod n =

= (a*(( a2)2)2*((( a2)2)2)2) mod n = (a*((( a*a2)2)2)2) mod n


С продуманным сохранением промежуточных результатов вам понадобится только шесть умножений:


(((((((a2 mod ri}* a)2 mod и)2 mod и)2 mod и)2 mod и)2 *a) mod n

Такой прием называется цепочкой сложений , или методом двоичных квадратов и умножения. Он использует простую и очевидную цепочку сложений, в основе которой лежит двоичное представление числа. На языке С это выглядит следующим образом:

long qe2(unsigned long x, unsigned long у, unsigned long n) {

unsigned long s, t, u; i;

s=l; t=x; u=y; (u) {

if(u&l) s=(s*t)%n; u>>l;

t=(t*t)%n;

}(s)

}


А вот другой, рекурсивный, алгоритм:

unsigned long fast_exp(unsigned long x, unsigned long у, unsigned long N)

{

unsigned long tmp;

if(y==l) return(x % N); (l^(x&l)) {

tmp= fast_exp(x,y/2,N);

return ( (tmp*tmp) %N) ;

else {

tmp = fast_exp(x,(y-l)/2,N);

tmp = (tmp*tmp) %N;

tmp = (tmp*x)%N;

return (tmp) ;

}

return 0;


Этот метод уменьшает количество операций, в среднем, до 1.5* k операций, где k - длина числа x в битах. Найти способ вычисления с наименьшим количеством операций - трудная проблема (было доказано, что послeдовательность должна содержать не меньше k- \ операций), но нетрудно снизить число операций до 1 . 1 * k или даже лучше при больших k.

Операция, обратная возведению в степень по модулю и, вычисляет дискретный логарифм Я дальше вкратце рассмотрю эту операцию.

Простые числа

Простым называется целое число, большее единицы, единственными множителями которого является 1 и оно само: оно не делится ни на одно другое число. Два - это простое число. Простыми являются и 73, 2521, 2365347734339 и 275б839-1. Существует бесконечно много простых чисел. Криптография, особенно криптография с открытыми ключами, часто использует большие простые числа (512 бит и даже больше).

Наибольший общий делитель

Два числа называются взаимно простыми, если у них нет общих множителей кроме 1 . Иными словами, e c-ли наибольший общий делитель а и n равен 1 . Это записывается как:


НОД(а,и)=1


Взаимно просты числа 15 и 28. 15 и 27 не являются взаимно простыми, а 13 и 500 - являются. Простое число взаимно просто со всеми другими числами, кроме чисел, кратных данному простому числу.

Одним из способов вычислить наибольший общий делитель двух чисел является алгоритм Эвклида. Эвклид описал этот алгоритм в своей книге, Элементы, написанной в 300 году до нашей эры. Он не изобрел его. Историки считают, что этот алгоритм лет на 200 старше. Это самый древний нетривиальный алгоритм, который дошел до наших дней, и он все еще хорош. Кнут описал алгоритм и его современные модификации в [863]. На языке С:

/* возвращает НОД (gcd) x и у */


int gcd (int x, int у) {g;(x < 0)(у < 0)

у = -у;

if (x + у == 0 ) ERROR ;

g = у;(x > 0) { g = x; = у % x;

у = g;

}

return g;

}


Обратные значения по модулю

Помните, что такое обратные значения? Обратное значение для 4 - 1/4, потому что 4*1/4 =1. В мире вычетов проблема усложняется:


*;c = 1 (mod 7)


Это уравнение эквивалентно обнаружению x и k, таких что


x = lk+l

где x и k - целые числа. Общая задача состоит в нахождении x, такого что


= (a*x) mod n


Это также можно записать как


а"1 =x (mod w)


Проблему обратных значений по модулю решить нелегко. Иногда у нее есть решение, иногда нет. Например, обратное значение 5 по модулю 14 равно 3. С другой стороны у числа 2 нет обратного значения по модулю 14.

В общем случае у уравнения а"1 = x (mod ri) существует единственное решение, если a и n взаимно просты. Если a и n не являются взаимно простыми, то а"1 = x (mod ri) не имеет решений. Если n является простым числом, то любое число от 1 до n -1 взаимно просто с n и имеет в точности одно обратное значение по модулю п.

Так, хорошо. А теперь как вы собираетесь искать обратное значение a по модулю и? Существует два пути. Обратное значение а по модулю n можно вычислить с помощью алгоритма Эвклида. Иногда это называется расширенным алгоритмом Эвклида.

Вот этот алгоритм на языке С++:


#define isEven(x) ((x & 0x01) == 0)

#define isOdd(x) (x& 0x01)

#define swap(x,y) (x^= у, y^= x, x^= у)

void ExtBinEuclid(int *u, int *v, int *ul, int *u2, int *u3) {

// предупреждение: u и v будут переставлены, если u<v int k, tl, t2, t3;

if (*u < *v) swap(*u<,*v);

for (k = 0; isEven(*u) && isEven(*v); ++k) {

*u>>=l; *v »1;

}

*ul = 1; *u2 = 0; *u3 = *u; tl = *v; t2 = *u - 1; t3 = *v;

do {

do {

if (isEven(*u3)) {

if (isOdd(*ul) || isOdd(*u2)) {

*ul += *v; *u2 += *u;

} *ul »* 1; *u2 »= 1; *u3 »= 1;

}

if (isEven(t3) II *u3 < t3) { swap(*ul,tl); smap(*u2,t2); smap(*u3,t3);

}

} while (isEven(*u3)); while (*ul < tl || *u2 < t2) { *ul += *v; *u2 += *u; }

ul -= tl; *u2 -= t2; *u3 -= t3; } while (t3 > 0) ;

while (*ul >= *v && *u2 >= *u) { *ul>l -= *v; *u2 -= *u;

}

*u «= k; *v «= k; *u3 « k; }

main(int argc, char **argv) { int a, b, gcd; if (argc < 3) {

cerr « "как использовать: xeuclid u v" « endl; return -1;

}

int u = atoi(argv[l]); int v = atoi(argv[2]); if (u <= 0 || v <= 0 ) {

cerr « "Аргумент должен быть положителен'" « endl; return -2;

}

// предупреждение: u и v будут переставлены если u < v

ExtBinEuclid(&u, &v, &a, &b, &gcd); cout « а «" * " « u « " + (-" « b « ") * " « v « " = " « gcd « endl; if (gcd == 1) « "Обратное значение " « v « " mod " « u « " is: « u - b « endl;

return 0;

Я не собираюсь доказывать, что это работает, или приводить теоретическое обоснование.

Алгоритм итеративен и для больших чисел может работать медленно.

Решение для коэффициентов

Алгоритм Эвклида можно использовать и для решения следующих проблем: дан массив из т переменных


Xi, х2,..., хт, найти массив т коэффициентов, u\, и2,..., ит, таких что

Mi * Xi+...+ Um * Хт, = 1


Малая теорема Ферма


Если т - простое число, и а не кратно т, то малая теорема Ферма утверждает атЛ = 1 (mod m)

(Пьер де Ферма (Pierre de Fermat), французский математик, жил с 1601 по 1665 год. Эта теорема не имеет ничего общего с его знаменитой теоремой.)


Функция Эйлера


Существует другой способ вычислить обратное значение по модулю n, но его не всегда возможно использoвать. Приведенным множеством остатков mod n называется подмножество полного множества остатков, члeны которого взаимно просты с п. Например, приведенное множество остатков mod 12 - это {1, 5, 7, 11}. Если n -простое число, то приведенное множество остатков mod n - это множество всех чисел от 1 до n-\. Для любого n, не равного 1,число 0 никогда не входит в приведенное множество остатков.

Функция Эйлера, которую также называют функцией фи Эйлера и записывают как ф(n), - это количество элементов в приведенном множестве остатков по модулю п. Иными словами, ф(n) - это количество положительных целых чисел, меньших n и взаимно простых с n (для любого и, большего

Если n - простое число, то ф(n) = n-\. Если n =pq, где р и q -простые числа, то ф(n)= (p - \)(q - 1). Эти числа появляются в некоторых алгоритмах с открытыми ключами, и вот почему. В соответствии с обобщением Эйлepa малой теоремы Ферма, если НОД(а,n) = 1, то


a ф(n) mod n = 1


Теперь легко вычислить а-1 mod n:

x = a ф(n)-1 mod n


Например, какое число является обратным для 5 по модулю 7? Так как 7 - простое число, ф(7) = 7 - 1 = 6. Итак, число, обратное к 5 по модулю 7, равно


6'1 mod 7 = 55 mod 7 = 3


Эти методы вычисления обратных значений можно расширить для более общей проблемы нахождения x (если НОД(а,n)= 1):


(a*x) mod n = b


Используя обобщение Эйлера, решаем


x = (b* a ф(n)-1 ) mod n


Используя алгоритм Эвклида, находим


x = (b* (a-1 modn)) mod n

В общем случае для вычисления обратных значений алгоритм Эвклида быстрее, чем обобщение Эйлера, особенно для чисел длиной порядка 500 бит. Если НОД(а,и) Ф 1, не все потеряно. В этом общем случае (a*x) mod n=b, может иметь или несколько решений, или ни одного.


Квадратичные вычеты


Если p - простое число, и а больше 0, но меньше p, то а представляет собой квадратичный вычет по модулю p, если x2 = a (mod p), для некоторых x Не все значения а соответствуют этому требованию. Чтобы а было квадратичным вычетом по n, оно должно быть квадратичным вычетом по модулю всех простых сомножителей п. Например, если p = 7, квадратичными вычетами являются числа 1, 2, и 4:


12 = 1 = 1 (mod 7)

2 = 4 = 4 (mod 7)

2 = 9 = 2 (mod 7)

2=16 = 2(mod7)

2 = 25 = 4 (mod 7) 62 = 3

6 = 1 (mod 7)


Заметьте, что каждый квадратичный вычет дважды появляется в этом списке. Значений x, удовлетворяющих любому из следующих уравнений, не существует:


x2 = 3 (mod 7)

x2 = 5 (mod 7)

x2 = 6 (mod 7)

Эти числа - 3, 5 и 6 - не являются квадратичными вычетами по модулю 7.

Хотя я этого и не делаю, несложно доказать, что когда p нечетно, существует в точности (p - l)/2 квадратичных вычетов по модулю p, и столько же чисел, не являющихся квадратичными вычетами по модулю р. Кроме того, если а - это квадратичный вычет по модулю p, то у а в точности два квадратных корня, один между 0 и (p-l)/2, а второй - между (p - l)/2 и (p - 1). Один из этих квадратных корней одновременно является квадратичным остатком по модулю p, он называется главным квадратным корнем

Если n является произведением двух простых чисел, p и q, то существует ровно (p - 1)(q - l)/4 квадратичных вычетов по модулю п. Квадратичный вычет по модулю n является совершенным квадратом по модулю и, потому что для того, чтобы быть квадратом по модулю и, вычет должен быть квадратом по модулю p и квадратом по модулю q. Например, существует одиннадцать квадратичных остатков mod 35: 1, 4, 9, 11, 15, 16, 21, 25, 29 и 30. У каждого квадратичного вычета ровно четыре квадратных корня.


Символ Лежандра


Символ Лежандра, L(a,p), определен, если а - это любое целое число, a p - простое число, большее, чем 2. Он равен 0, 1 или - 1 .

L(a,p)= 0, если а делится на р.

L(a,p)= 1, если а - квадратичный вычет по модулю р.

L(a,p) = -1, если а не является квадратичным вычетом по модулю р.

L(a,p) можно рассчитать следующим образом: L(a,p) = a(p-1)/2 mod p Или можно воспользоваться следующим алгоритмом:

. Если а = 1, то L(a,p) = 1

  1. Если а четно, то L(a,p) = L(a/2,p) * (-l)^2-'>78
  2. Если а нечетно (и * 1), то L(a,p)= Цр mod а,^)*(-1)(3*3-1)/8

Обратите внимание, что этот метод также является эффективным способом определить, является ли a квадратичным вычетом по модулю p (для простого числа p).


Символ Якоби


Символ Якоби, J(a,n), представляет собой обобщение символа Лежандра на составные модули, он определяется для любого целого a и любого нечетного целого п. Функция удобна при проверке на простоту. Символ Якoби является функцией на множестве полученных вычетов делителей n и может быть вычислен по различным формулам.Вот один из способов:

Определение 1 : J(a,n) определен, только если n нечетно.

Определение 2: J(0,n) = 0.

Определение 3: Если n - простое число, то символ Якоби ](a,n) = 0, если а делится на п.

Определение 4: Если n - простое число, то символ Якоби J(a,n) = 1, если а - квадратичный вычет по модулю п.

Определение 5: Если n - простое число, то символ Якоби ](a,n) = -1, если а не является

квадратичным вычетом по модулю п.

Определение 6: Если n - составное число, то символ Якоби J(a,n) = J(a,p1)* ... * J(a,pm), где p1…pm - это разложение n на простые сомножители.

Следующий алгоритм рекурсивно рассчитывает символ Якоби:

Правило 1: J(l,n) = 1

Правило 2: J(a*b,n} = J(a,n)* J(b,n)

Правило 3: J(2,n) =, если (n2-1) /8 нечетно, и -1 в противном случае

Правило 4: J(a,n)= J((a mod n),n)

Правило 5: J(a, bi*b2) = J(a, b1)* J(a, b2)

Правило 6: Если наибольший общий делитель a и b = 1, а также a и b нечетны:

Правило 6а: J(a,b)= J(b, a), если (a - 1)(b - l)/4 четно

Правило 6b: J(a,b)= -J(b, a), если (a - 1)(b - l)/4 нечетно

Алгоритм на языке С: (кажется уже начал объяснять сам С)

int jacobi(int a, int b) {g;(odd(b)); (а >= b) a %= b; /* по правилу 4 */

if (а == 0) return 0; /* по определению 1 */

if (а == 1) return 1; /* по правилу 1 */

if (а < 0)

if ((b-l)/2 % 2 == 0)

return jacobi(-a,b); else

return -jacobi(-a,b); if (а % 2 == 0) /* а четно */

if (((b*b -1)/8) % 2 == 0)

return +jacobi(a/2,b); else

return -jacobi(a/2,b); /* по правилам 3 и 2 */ g = gcd(a,b);(odd(a)); /* это обеспечивается проверкой (а % 2 == 0) */ if (g == а) /* b делится на а */

return 0; /* по правилу 5 */ else if (g '= 1)

return jacobi(g,b)*jacobi(a/g,b); /* по правилу 2 */ else if (((a-l)*(b-l)/4) % 2 == 0)

return +jacobi(b,a); /* по правилу 6a */ else

return -jacobi(b,a); /* по правилу 6b */ }


Если заранее известно, что n - простое число, вместо использования предыдущего алгоритма просто вычиcлите a((n-l)/2) mod n, в этом случае J(a,n) эквивалентен символу Лежандра.

Символ Якоби нельзя использовать для определения того, является ли a квадратичным вычетом по модулю n (если, конечно, n не является простым числом). Обратите внимание, что если J( a,n) = 1 и n - составное число, то утверждение, что а является квадратичным вычетом по модулю и, не обязательно будет истиной. Например:


J(7,143) = J(7,11)* J(7,13) = (-1)(-1) = 1


Однако не существует таких целых чисел x, что x2 = 1 (mod 143).

Целые числа Блюма

Если p и q - два простых числа, конгруэнтных 3 по модулю 4, то n = pq иногда называют целым числом Блюма. Если n - это целое число Блюма, у каждого квадратичного вычета ровно четыре квадратных корня, один из которых также является квадратом - это главный квадратный корень. Например, главный квадратный корень 139 mod 437 - это 24. Остальные три корня - это 185, 252 и 413.


Вычисление в поле Галуа


Не тревожьтесь, все это мы уже делали. Если n - простое число или степень большого простого числа, то мы получаем то, что математики называют конечным полем. В честь этого мы используем p вместо п. В действительности этот тип конечного поля настолько замечателен, что математики дали ему собственное имя - поле Галуа, обозначаемое как GF(p). в честь Эвариста Галуа, французского математика, жившего в девятнадцатом веке и успевшего значительно продвинуть теорию чисел, прежде чем в 20 лет он был убит на дуэли.)

В поле Галуа определены сложение, вычитание, умножение и деление на ненулевые элементы. Существует нейтральный элемент для сложения - 0 - и для умножения - 1. Для каждого ненулевого числа существует единственное обратное число (это не было бы так, если бы p не было бы простым числом). Выполняются коммутативный, ассоциативный и дистрибутивный законы.

Арифметика поля Галуа широко используется в криптографии. В нем работает вся теория чисел, поле с o-держит числа только конечного размера, при делении отсутствуют ошибки округления. Многие криптосистемы основаны на GF(p), где з - это большое простое число.

Чтобы еще более усложнить вопрос, криптографы также используют арифметику по модулю неприводимых многочленов степени n, коэффициентами которых являются целые числа по модулю q, где q - это простое число. Эти поля называются GF(qт). Используется арифметика по модулю p(x), где р(х) - это неприводимый многочлен степени п.

При обсуждении полиномов термин "простое число" заменяется термином " неприводимый многочлен". Пoлином называется неприводимым, если его нельзя представить в виде двух других полиномов (конечно же, кроме 1 и самого полинома). Полином x2 + 1 неприводим над целыми числами, а полином x3 + 2 x2 + x не является неприводимым, он может быть представлен как


x(x + l)(x + 1).


Полином, который в данном поле является генератором, называется примитивным или базовым, все его кoэффициенты взаимно просты.

Для поля Галуа GF(2n) криптографы любят использовать в качестве модулей трехчлены p(x) = x" + x + 1, так как длинная строка нулей между коэффициентами при x" и x позволяет просто реализовать быстрое умножение по модулю. Полином должен быть примитивным, в противном случае математика не будет работать, x" + x + 1 примитивен для следующих значений n, меньших чем 1000

1, 3, 4, 6, 9, 15, 22, 28, 30,46, 60, 63, 127, 153, 172, 303,471, 532, 865, 900


Существуют аппаратные реализации GF(2127), где px = x121 + x + 1.

Разложение на множители

Разложить число на множители - значит найти его простые сомножители.


= 2*5

= 2*2*3*5

=41*61*101

- 1 =3391*23279*65993*1868569*1066818132868207


Разложение на множители является одной из древнейших проблем теории чисел. Этот процесс несложен, но требует времени. Это пока остается так, но ряд сдвигов в этом искусстве все же произошел. Сегодня самым лучшим алгоритмом является:

Решето числового поля чисел (Number field sieve, NFS).

Решето общего числового поля - это самый быстрый из известных алгоритм для чисел размером 1 10 и более разрядов . В своем первоначальном виде он был непрактичен, но за последние несколько лет он был последовательно улучшен . NFS все еще слишком нов, чтобы бить рекорды разложения на множители, но скоро все перемeнится. Ранняя версия использовалась для разложения на множители девятого числа Ферма: 2512 + 1 .

Другие алгоритмы, вытесненные NFS:

Квадратичное решето. Это самый быстрый из известных и чаще всего использовавшийся алгоритм для чисел, длина которых меньше 1 10 десятичных разрядов. Более быстрая версия этого алгоритма называется множественным полиномиальным квадратичным решетом. Самая быстрая версия называется двойной вариацией множественного полиномиального квадратичного решета с большим простым числом.

Метод эллиптической кривой. Этот метод использовался для поиска не более, чем 43-разрядных множителей.

Проверка делением. Этот самый старый алгоритм разложения на множители состоит из проверки каждого простого числа, меньшего или равного квадратному корню из раскладываемого числа.

В 1970 году большой новостью стало разложение на множители 41-разрядного трудного числа. ("Трудным" является такое число, у которого нет маленьких множителей, и которое не обладает специальной формой, позволяющей упростить процесс.) Десять лет спустя разложение в два раз более длинного числа заняло лишь несколько часов на компьютере Cray .

В 1988 году Карл Померанс (Carl Pomerance), используя обычные СБИС, спроектировал устройство для paзложения на множители . Размер числа, которое можно было разложить, зависел только от размеров устройства, которое так и не было построено.

В 1993 году с помощью квадратичного решета было разложено на множители 120-разрядное трудное число. Расчет, потребовавший 825 mips-лет, был выполнен за три месяца реального времени.

Сегодня для разложения на множители используются компьютерные сети. Для разложения 1 16_разрядного числа в течение нескольких мeсяцев использовалось свободное время массива компьютеров, разбросанных по всему миру, - 400 mips-лет, потребовалось в сумме.

В марте 1994 года с помощью двойной вариации множественного полиномиального QS командой мaтематиков под руководством Ленстры было разложено на множители 129-разрядное (428-битовое) число. Вычисления выполнялись добровольцами в Internet - в течение восьми месяцев трудились 600 человек и 1600 компьютеров, возможно, самый большой в истории многопроцессорный конгломерат. Трудоемкость вычислений была в диапазоне от 4000 до 6000 mips-лет. Компьютеры соединялись по электронной почте, передавая свои результаты в центральное хранилище, где выполнялся окончательный анализ. В этих вычислениях использовaлись QS и теория пятилетней давности, NFS мог бы ускорить выполнение расчетов раз в десять . В cooтветствии с : "Мы делаем вывод, что широко используемые 512-битовые модули RSA могут быть вскрыты организацией, готовой потратить несколько миллионов долларов и подождать несколько месяцев." По оценкам авторов разложение 512-битового числа в 100 раз более трудоемко при использовании той же техники и только в 10 сложнее при использовании NFS и современной техники.


Квадратные корни по модулю n


Если n - произведение двух простых чисел, то возможность вычислить квадратные корни по модулю n вычислительно эквивалентна возможности разложить число n на множители. Другими словами, тот, кто знает простые множители числа n, может легко вычислить квадратные корни любого числа по модулю n, но для любого другого вычисление окажется таким же трудным, как и разложение на простые множители числа п.

Ну вот вроде с математическими основами разобрались. Математика дальше будет нам встречается повсеместно, но базовые знания уже есть..

Собственно говоря уже можно переходить к самим алгоритмам, но кажется я упустил некоторые моменты- а именно XOR, одноразовые блокноты и ключи (нет не от квартиры).


Простое XOR


XOR представляет собой операцию "исключающее или" : '^' в языке С или Q в математической нотации. Это обычная операция над битами :


Å 0 = 0

Å 1 = 1

Å 0 = 1

Å 1 = 1


Также заметим, что:


a Å a =0

aÅbÅb=a


Казалось бы, запутанный алгоритм простого XOR по сути является ничем иным, как полиалфавитным шифром Вигенера. Здесь он упоминается только из-за распространенности в коммерческих программных продуктах, по крайней мере в мире MS-DOS и Macintosh. К сожалению, если о программе компьютерной безопасности заявляется, что это "патентованный" алгоритм шифрования, значительно более быстрый, чем DES, то скорее всего используется какой-то вариант следующего .


void main (int argc, char *argv[])

{

FILE *fl, *fo;

char *cp;

int с;

if ((cp = argv[l]) && *cp'= '\0') {

if ((fi = fopen(argvl[2], "rb")) '= NULL) {

if ((fo = fopen(argv[3], "wb")) '= NULL) { while ((c = getc(fi)) '= EOF) { if ('*cp) cp = argv[l]; c^ = * (cp++) ; putc (с, fo) ; }

fclose (fo) ; } fclose(fi) ;


Это симметричный алгоритм. Открытый текст подвергается операции "исключающее или" вместе с ключeвым текстом для получения шифротекста. Так как повторное применение операции XOR восстанавливает оригинал для шифрования и дешифрирования используется одна и та же программа :


P Å K=C

C Å K = P


Настоящей безопасности здесь никогда не было. Этот тип шифрования легко вскрывается, даже без компьтетера.

Для примера:предположим, что открытый текст использует английский язык. Более того, пусть длина ключа любое нeбольшое число байт. Ниже описано, как взломать этот шифр:

  • Определим длину ключа с помощью процедуры, известной как подсчет совпадений Применим операцию XOR к шифротексту, используя в качестве ключа сам шифротекст с различными смещeниями, и подсчитаем совпадающие байты. Если величина смещения кратна длине ключа, то совпадет свыше 6 процентов байтов. Если нет, то будут совпадать меньше чем 0.4 процента (считая, что обычный ASCII текст кодируется случайным ключом, для других типов открытых текстов числа будут дрyгими). Это называется показателем совпадений. Минимальное смещение от одного значения, кратного длине ключа, к другому и есть длина ключа.
  • Сместим шифротекст на эту длину и проведем операцию XOR для смещенного и оригинального шифротекстов. Результатом операции будет удаления ключа и получение открытого текста, подвергнутого операции XOR с самим собой, смещенным на длину ключа. Так как в английском языке на один байт приходится 1.3 бита действительной информации, существующая значительная избыточность позволяет определить способ шифрования.

Одноразовые блокноты


Помните я говорил что есть невзлавыеваемая система сокрытия информации? Он называется одноразовым блокнотом и был изобретен в 1917 году Мэйджором Джозефом Моборном (Major Joseph Mauborgne) и Гилбертом Вернамом (Gilbert Vernam) из AT&T . В классическом понимании одноразовый блокнот является большой неповторяющейся последовательностью символов ключа, распределенных случайным образом, написанных на кусочках бумаги и приклеенных к листу блокнота. Отправитель использовал каждый символ ключа блокнота для шифрования только одного символа открытого текста. Шифрование представляет собой сложение по модулю 26 (для английского языка), или 33 (для кириллического) символа открытого текста и символа ключа из однoразового блокнота.

Каждый символ ключа используется только единожды и для единственного сообщения . Отправитель шифрует сообщения и уничтожает использованные страницы блокнота. Получатель, в свою очередь, используя точно такой же блокнот, дешифрирует каждый символ шифротекста . Расшифровав сообщение, получатель уничтожает соответствующие страницы блокнота или часть ленты . Новое сообщение -новые символы ключа. Например, если сообщением является:


ONETMEPAD

а ключевая последовательность блокноте:

TBFRGFARFM

то шифротекст будет выглядеть как:

IPKLPSFHGQ так как

Q + Т mod 26 = I+ В mod 26 = P

E + F mod 26 = К и.т.д.

В предположении, что злоумышленник не сможет получить доступ к одноразовому блокноту, использованному для шифрования сообщения, эта схема совершенно безопасна. Данное шифрованное сообщение на вид соответствует любому открытому сообщению того же размера.

Так как все ключевые последовательности совершенно одинаковы (символы ключа генерируются случайным образом), у противника отсутствует информация, позволяющая подвергнуть шифротекст криптоанaлизу. Кусочек шифротекста может быть похож на:


POYYAEAAZX

что дешифрируется как:

SALMONEGGS

или на:

BXEGBMTMXM

что дешифрируется как:

GREENFLUID


Повторю еще раз: так как все открытые тексты равновероятны, у криптоаналитика нет возможности определить, какой из открытых текстов является правильным. Случайная ключевая последовательность, сложенная с неслучайным открытым текстом, дает совершенно случайный шифротекст, и никакие вычислительные мощнoсти не смогут это изменить.

Необходимо напомнить, что символы ключа должны генерироваться случайным образом . Любые попытки вскрыть такую схему сталкиваются со способом, которым создается последовательность символов ключа . Использование генераторов псевдослучайных чисел не считается, у них всегда неслучайные свойства . Если вы используете действительно случайный источник- это совершенно безопасно.

Другой важный момент: ключевую последовательность никогда нельзя использовать второй раз. Даже если вы используете блокнот размером в несколько гигабайт, то если криптоаналитик получит несколько текстов с перекрывающимися ключами, он сможет восстановить открытый текст . Он сдвинет каждую пару шифротекстов относительно друг друга и подсчитает число совпадений в каждой позиции. Если шифротексты смещены прaвильно, соотношение совпадений резко возрастет - точное значение зависит от языка открытого текста . С этой точки зрения криптоанализ не представляет труда. По этому, не используйте ключевую последовательность повторно.

Данная система как нельзя лучше подтверждает то что всё гениальное- просто…


Управление ключами


Кроме выбора подходящей для конкретной ИС (информационаая система) криптографической системы, важная проблема - управление ключами. Как бы ни была сложна и надежна сама криптосистема, она основана на использовании ключей. Если для обеспечения конфиденциального обмена информацией между двумя пользователями процесс обмена ключами тривиален, то в ИС, где количество пользователей составляет десятки и сотни управление ключами - серьезная проблема.

Под ключевой информацией понимается совокупность всех действующих в ИС ключей. Если не обеспечено достаточно надежное управление ключевой информацией, то завладев ею, злоумышленник получает неограниченный доступ ко всей информации.

Управление ключами - информационный процесс, включающий в себя три элемента:

  • генерацию ключей;
  • накопление ключей;
  • распределение ключей.

Рассмотрим, как они должны быть реализованы для того, чтобы обеспечить безопасность ключевой информации в ИС.


Генерация ключей


В самом начале разговора о криптографических методах было сказано, что не стоит использовать неслучайные ключи с целью легкости их запоминания. В серьезных ИС используются специальные аппаратные и программные методы генерации случайных ключей. Как правило используют датчики ПСЧ. Однако степень случайности их генерации должна быть достаточно высоким. Идеальным генераторами являются устройства на основе натуральных случайных процессов. Например, появились серийные образцы генерации ключей на основе белого радиошума. Другим случайным математическим объектом являются десятичные знаки иррациональных чисел, например p или е, которые вычисляются с помощью стандартных математических методов.

В ИС со средними требованиями защищенности вполне приемлемы программные генераторы ключей, которые вычисляют ПСЧ как сложную функцию от текущего времени и (или) числа, введенного пользователем.


Накопление ключей


Под накоплением ключей понимается организация их хранения, учета и удаления. Поскольку ключ является самым привлекательным для злоумышленника объектом, открывающим ему путь к конфиденциальной информации, то вопросам накопления ключей следует уделять особое внимание.

Секретные ключи никогда не должны записываться в явном виде на носителе, который может быть считан или скопирован.

В достаточно сложной ИС один пользователь может работать с большим объемом ключевой информации, и иногда даже возникает необходимость организации мини-баз данных по ключевой информации. Такие базы данных отвечают за принятие, хранение, учет и удаление используемых ключей.

Итак, каждая информация об используемых ключах должна храниться в зашифрованном виде. Ключи, зашифровывающие ключевую информацию называются мастер-ключами. Желательно, чтобы мастер-ключи каждый пользователь знал наизусть, и не хранил их вообще на каких-либо материальных носителях.

Очень важным условием безопасности информации является периодическое обновление ключевой информации в ИС. При этом переназначаться должны как обычные ключи, так и мастер-ключи. В особо ответственных ИС обновление ключевой информации желательно делать ежедневно.

Вопрос обновления ключевой информации связан и с третьим элементом управления ключами - распределением ключей.


Распределение ключей


Распределение ключей - самый ответственный процесс в управлении ключами. К нему предъявляются два требования:

Оперативность и точность распределения

  • Скрытность распределяемых ключей

В последнее время заметен сдвиг в сторону использования криптосистем с открытым ключом, в которых проблема распределения ключей отпадает. Тем не менее распределение ключевой информации в ИС требует новых эффективных решений.

Распределение ключей между пользователями реализуются двумя разными подходами:

  1. Путем создания одного ли нескольких центров распределения ключей. Недостаток такого подхода состоит в том, что в центре распределения известно, кому и какие ключи назначены и это позволяет читать все сообщения, циркулирующие в ИС. Возможные злоупотребления существенно влияют на защиту.
  2. Прямой обмен ключами между пользователями информационной системы. В этом случае проблема состоит в том, чтобы надежно удостоверить подлинность субъектов.

В обоих случаях должна быть гарантирована подлинность сеанса связи. Это можно обеспечить двумя способами:

. Механизм запроса-ответа, который состоит в следующем. Если пользователь А желает быть уверенным, что сообщения который он получает от В, не являются ложными, он включает в посылаемое для В сообщение непредсказуемый элемент (запрос). При ответе пользователь В должен выполнить некоторую операцию над этим элементом (например, добавить 1). Это невозможно осуществить заранее, так как не известно, какое случайное число придет в запросе. После получения ответа с результатами действий пользователь А может быть уверен, что сеанс является подлинным. Недостатком этого метода является возможность установления хотя и сложной закономерности между запросом и ответом.

. Механизм отметки времени (временной штемпель). Он подразумевает фиксацию времени для каждого сообщения. В этом случае каждый пользователь ИС может знать, насколько старым является пришедшее сообщение.

В обоих случаях следует использовать шифрование, чтобы быть уверенным, что ответ послан не злоумышленником и штемпель отметки времени не изменен.

При использовании отметок времени встает проблема допустимого временного интервала задержки для подтверждения подлинности сеанса. Ведь сообщение с временным штемпелем в принципе не может быть передано мгновенно. Кроме этого компьютерные часы получателя и отправителя не могут быть абсолютно синхронизированы. Какое запаздывание штемпеля считать подозрительным.

Поэтому в реальных ИС, например в системах оплаты кредитных карточек используется именно второй механизм установления подлинности и защиты от подделок. Используемый интервал составляет от одной до нескольких минут. Большое число известных способов кражи электронных денег, основано на вклинивании в этот промежуток с подложными запросами на снятии денег.

Для обмена ключами можно использовать криптосистемы с открытым ключом, используя тот же алгоритм RSA.

Но весьма эффективным оказался алгоритм Диффи-Хелмана, позволяющий двум пользователям без посредников обменяться ключом, который может быть использован затем для симметричного шифрования.


Алгоритм Диффи-Хеллмана


Диффи и Хелман предложили для создания криптографических систем с открытым ключом функцию дискретного возведения в степень.

Необратимость преобразования в этом случае обеспечивается тем, что достаточно легко вычислить показательную функцию в конечном поле Галуа состоящим из p элементов. (p - либо простое число, либо простое в любой степени). Вычисление же логарифмов в таких полях - значительно более трудоемкая операция.

Если y=ax,, 1<x<p-1, где - фиксированный элемент поля GF(p), то x=loga y над GF(p). Имея x, легко вычислить y. Для этого потребуется 2 ln(x+y) операций умножения.

Обратная задача вычисления x из y будет достаточно сложной. Если p выбрано достаточно правильно, то извлечение логарифма потребует вычислений, пропорциональных

L(p) = exp { (ln p ln ln p)0.5 }


Для обмена информацией первый пользователь выбирает случайное число x1, равновероятное из целых 1...p-1. Это число он держит в секрете, а другому пользователю посылает число

y1 = ax mod p

Аналогично поступает и второй пользователь, генерируя x2 и вычислив y2, отправляя его первому пользователю. В результате этого они могут вычислять k12 = ax1x2 mod p.

Для того, чтобы вычислить k12, первый пользователь возводит y2 в степень x1. То же делает и второй пользователь. Таким образом, у обоих пользователей оказывается общий ключ k12, который можно использовать для шифрования информации обычными алгоритмами. В отличие от алгоритма RSA, данный алгоритм не позволяет шифровать собственно информацию.

Не зная x1 и x2, злоумышленник может попытаться вычислить k12, зная только перехваченные y1 и y2. Эквивалентность этой проблемы проблеме вычисления дискретного логарифма есть главный и открытый вопрос в системах с открытым ключом. Простого решения до настоящего времени не найдено. Так, если для прямого преобразования 1000-битных простых чисел требуется 2000 операций, то для обратного преобразования (вычисления логарифма в поле Галуа) - потребуется около 1030 операций.

Как видно, при всей простоте алгоритма Диффи-Хелмана, вторым его недостатком по сравнению с системой RSA является отсутствие гарантированной нижней оценки трудоемкости раскрытия ключа.

Кроме того, хотя описанный алгоритм позволяет обойти проблему скрытой передачи ключа, необходимость аутентификации остается. Без дополнительных средств, один из пользователей не может быть уверен, что он обменялся ключами именно с тем пользователем, который ему нужен. Опасность имитации в этом случае остается.

В качестве обобщения сказанного о распределении ключей следует сказать следующее. Задача управления ключами сводится к поиску такого протокола распределения ключей, который обеспечивал бы:

  • возможность отказа от центра распределения ключей;
  • взаимное подтверждение подлинности участников сеанса;
  • подтверждение достоверности сеанса механизмом запроса-ответа, использование для этого программных или аппаратных средств;
  • использование при обмене ключами минимального числа сообщений.

Использование блуждающих ключей


Как было неоднократно отмечено, проблема распределения ключей является наиболее острой в крупных информационных системах. Отчасти эта проблема решается (а точнее снимается) за счет использования открытых ключей. Но наиболее надежные криптосистемы с открытым ключом типа RSA достаточно трудоемки, а для шифрования мультимедийных данных и вовсе не пригодны.

Оригинальные решения проблемы блуждающих ключей активно разрабатываются специалистами. Эти системы являются некоторым компромиссом между системами с открытыми ключами и обычными алгоритмами, для которых требуется наличие одного и того же ключа у отправителя и получателя.

Идея метода достаточно проста.

После того, как ключ использован в одном сеансе по некоторому правилу он сменяется другим. Это правило должно быть известно и отправителю, и получателю. Зная правило, после получения очередного сообщения получатель тоже меняет ключ. Если правило смены ключей аккуратно соблюдается и отправителем и получателем, то в каждый момент времени они имеют одинаковый ключ. Постоянная смена ключа затрудняет раскрытие информации злоумышленником.

Основная задача в реализации этого метода - выбор эффективного правила смены ключей. Наиболее простой путь - генерация случайного списка ключей. Смена ключей осуществляется в порядке списка. Однако, очевидно список придется каким-то образом передавать.

Другой вариант - использование математических алгоритмов, основанных на так называемых перебирающих последовательностях. На множестве ключей путем одной и той же операции над элементом получается другой элемент. Последовательность этих операций позволяет переходить от одного элемента к другому, пока не будет перебрано все множество.

Наиболее доступным является использование полей Галуа. За счет возведения в степень порождающего элемента можно последовательно переходить от одного числа к другому. Эти числа принимаются в качестве ключей.

Ключевой информацией в данном случае является исходный элемент, который перед началом связи должен быть известен и отправителю и получателю.

Надежность таких методов должна быть обеспечена с учетом известности злоумышленнику используемого правила смены ключей.

Интересной и перспективной задачей является реализация метода блуждающих ключей не для двух абонентов, а для достаточно большой сети, когда сообщения пересылаются между всеми участниками.


Формальный анализ протоколов проверки подлинности и обмена ключами


Проблема выделения безопасного сеансового ключа для пары компьютеров (или людей) в сети настолько фундаментальна, что стала причиной многих исследований. Некоторые исследования заключались в разработке протоколов. Это, в свою очередь, привело к появлению более важной и интересной задачи: формальному анализу протоколов проверки подлинности и обмена ключами. Иногда прорехи в протоколах, кажущихся вполне надежными, обнаруживались спустя много лет пoсле их разработки, и разработчикам потребовались средства, позволяющие сразу же проверять безопасность протокола. Хотя большая часть этого инструментария применима и к более общим криптографическим протoколам, особое внимание уделялось проверке подлинности и обмену ключами.

Существует четыре основных подхода к анализу криптографических протоколов:

  1. Моделирование и проверка работы протокола с использованием языков описания и средств проверки, не разработанных специально для анализа криптографических протоколов.
  2. Создание экспертных систем, позволяющих конструктору протокола разрабатывать и исследовать различные сценарии.
  3. Выработка требований к семейству протоколов, используя некую логику для анализа понятий "знание" и "доверие".
  4. Разработка формальных методов, основанных на записи свойств криптографических систем в алгебраическом виде.

Первый из подходов пытается доказать правильность протокола, рассматривая его как обычную компьютеpную программу. Ряд исследователей представляют протокол как конечный автомат, другие используют расширения методов исчисления предиката первого порядка, а третьи для анализа протоколов используют языки описания. Однако, доказательство правильности отнюдь не является доказательством безопасности, и этот подход потерпел неудачу при анализе многих "дырявых" протоколов . И хотя его применение поначалу широко изучалось, с ростом популярности третьего из подходов работы в этой области были пeреориентированы.

Во втором подходе для определения того, может ли протокол перейти в нежелательное состояние (например, потеря ключа), используются экспертные системы. Хотя этот подход дает лучшие результаты при поиске "дыр", он не гарантирует безопасности и не предоставляет методик разработки вскрытий . Он хорош для проверки того, содержит ли протокол конкретную "дыру", но вряд ли способен обнаружить неизвестные "дыры" в протоколе .

Третий подход гораздо популярнее. Он был впервые введен Майклом Бэрроузом, Мартином Абэди и Роджером Неедхэмом. Они разработали формальную логическую модель для анализа знания и доверия, названную БАН-логикой БАН-логика является наиболее широко распространена при анализе протоколов проверки подлинности. Она рассматривает подлинность как функцию от цeлостности и новизны, используя логические правила для отслеживания состояния этих атрибутов на протяжении всего протокола. Хотя были предложены различные варианты и расширения, большинство разработчиков пр o-токолов до сих пор обращаются к оригинальной работе.

БАН-логика не предоставляет доказательство безопасности, она может только рассуждать о проверке подлинности. Она является простой, прямолинейной логикой, легкой в применении и полезной при поиске "дыр" . Вот некоторые предложения БАН-логики:

  • A считает X (A действует, как если бы X являлось истиной )
  • A видит X (Кто-то послал сообщение, содержащее X, А, который может прочитать и снова передать X - возможно после дешифрирования )
  • A сказал X (В некоторый момент времени A послал сообщение, которое содержит предложение X Не известно, как давно было послано сообщение, и было ли оно послано в течении текущего выполнения протокола Известно, что A считал X, когда говорил X )

И так далее. БАН-логика также предоставляет правила для рассуждения о доверии протоколу. Для доказательства чего-либо в протоколе или для ответа на какие-то вопросы к логическим предложениям о протоколе можно применить эти правила. Например, одним из правил является правило о значении сообщения:

Если A считает, что у A и B общий секретный ключ, К, и A видит X, шифрованное К, и A не шифровала Хc помощью К, TO A считает, что B сказал X

Другим является правило подтверждения метки времени:

Если A считает, что X могло быть сказано только недавно, и, что B X когда-то сказал X, TO A считает, что B считает X

БАН-анализ делится на четыре этапа:

  1. Преобразуйте протокол к идеальной форме, используя описанные выше предложения.
  2. Добавьте все предположения о начальном состоянии протокола.
  3. Присоедините логические формулы к предложениям, получая утверждения о состоянии системы после каждого предложения.
  4. Примените логические постулаты к утверждениям и предположениям, чтобы раскрыть состояние доверия участников протокола.

Четвертый подход к анализу криптографических протоколов предлагает моделировать протокол как алгебраическую систему, выразить состояние знания участников о протоколе и затем проанализировать достижимость определенных состояний. Этот подход пока не привлек столько внимания, как формальная логика, но состояние дел меняется.

Применение формальных методов к криптографическим протоколам представляет собой качественно новую идею, и трудно обрисовать, к чему может привести ее реализация . С этой точки зрения слабейшим звеном кaжется процесс формализации.

Ну кажется все! Можно переходить к третьей части:

Практика


Стандарт шифрования данных DES (Data Encryption Standard)


Стандарт шифрования данных DES (Data Encryption Standard), который ANSI называет Алгоритмом шифрования данных DEA (Data Encryption Algorithm), a ISO - DEA-1, за 20 лет стал мировым стандартом. Хотя на нем и появился налет старости, он весьма прилично выдержал годы криптоанализа и все еще остается безопаcным по отношению ко всем врагам, кроме, возможно, самых могущественных

В 1972 году Национальное Бюро Стандартов (National Bureau of Standards- NSA, аналог ГОСТ ), выступило инициатором программы защиты линий связи и компьютерных данных. Одной из целей этой программы была разработка единого, стандартного криптографического алгоритма. Этот алгоритм мог бы быть проверен и сеpтифицирован, а использующие его различные криптографические устройства могли бы взаимодействовать. Он мог бы, к тому же, быть относительно недорогим и легко доступным.

мая 1973 года в Federal Register НБС опубликовало требования к криптографическому алгоритму, котoрый мог бы быть принят в качестве стандарта. Было приведено несколько критериев оценки проекта:

  • Алгоритм должен обеспечивать высокий уровень безопасности.
  • Алгоритм должен быть полностью определен и легко понятен.
  • Безопасность алгоритма должна основываться на ключе и не должна зависеть от сохранения в тайне сaмого алгоритма.
  • Алгоритм должен быть доступен всем пользователям.
  • Алгоритм должен позволять адаптацию к различным применениям.
  • Алгоритм должен позволять экономичную реализацию в виде электронных приборов.
  • Алгоритм должен быть эффективным в использовании.
  • Алгоритм должен предоставлять возможности проверки.
  • Алгоритм должен быть разрешен для экспорта.

Реакция общественности показала, что к криптографическому стандарту существует заметный интерес, но опыт в этой области чрезвычайно мал. Ни одно из предложений не удовлетворяло предъявленным требованиям

27 августа 1972 года в Federal Register НБС опубликовало повторное предложение. Наконец, у Бюро появился подходящий кандидат: алгоритм под именем Люцифер, в основе которого лежала разработка компании IBM, выполненная в начале 70-х. В IBM существовала целая команда криптографов, работавшая в Кингстоне (Kingston) и Иорктаун Хайтс (Yorktown Heights), в которую входили Рой Адлер, Дон Копперсмит? Хорст Фейстель, Эдна Кроссман, Алан Конхейм , Карл Майер, Билл Ноц, Линн Смит, Уолт Тачмен и Брайант Такерман .Несмотря на определенную сложность алгоритм был прямолинеен. Он использовал только простые логические операции над небольшими группами битов и мог быть довольно эффективно реализован в аппаратуре.

В стандарте DES было оговорено, что он будет пересматриваться каждые пять лет. В 1983 DES был повтоpно сертифицирован без всяких проблем. 6 марта 1987 года в Federal Register НБС попросило прокомментирoвать предложение на следующие пять лет. НБС предложило на обсуждение следующие три альтернативы : вновь подтвердить стандарт на следующие пять лет, отказаться от стандарта или пересмотреть применимость стандарта.

НБС и АНБ пересмотрели стандарт. В этот раз АНБ было задействовано в большей степени. Первоначально АНБ объявило, что оно не сертифицирует стандарт повторно. Проблема была не в том, что DES действительно был взломан, и даже не в том, что он, может быть, был взломан. По видимoму, предполагалось, что он вот-вот будет взломан.

Описание DES

DES представляет собой блочный шифр, он шифрует данные 64-битовыми блоками. С одного конца агoритма вводится 64-битовый блок открытого текста, а с другого конца выходит 64-битовый блок шифротекста. DES является симметричным алгоритмом: для шифрования и дешифрирования используются одинаковые агoритм и ключ (за исключением небольших различий в использовании ключа).

Длина ключа равна 56 битам. (Ключ обычно представляется 64-битовым числом, но каждый восьмой бит используется для проверки четности и игнорируется. Биты четности являются наименьшими значащими битами байтов ключа.) Ключ, который может быть любым 56-битовым числом, можно изменить в любой момент врeмени. Ряд чисел считаются слабыми ключами, но их можно легко избежать. Безопасность полностью определяется ключом.

На простейшем уровне алгоритм не представляет ничего большего, чем комбинация двух основных методов шифрования: смещения и диффузии. Фундаментальным строительным блоком DES является применение к тексту единичной комбинации этих методов (подстановка, а за ней - перестановка), зависящей от ключа. Такой блок называется этапом. DES состоит из 16 этапов, одинаковая комбинация методов применяется к открытому тексту 16 раз



Алгоритм использует только стандартную арифметику 64-битовых чисел и логические операции, поэтому он легко реализовывался в аппаратуре второй половины 70-x. Изобилие повторений в алгоритме делает его идeальным для реализации в специализированной микросхеме. Первоначальные программные реализации были довольно неуклюжи, но сегодняшние программы намного лучше.


Схема алгоритма


DES работает с 64-битовым блоком открытого текста. После первоначальной перестановки блок разбивается на правую и левую половины длиной по 32 бита. Затем выполняется 16 этапов одинаковых действий, называeмых функцией f, в которых данные объединяются с ключом. После шестнадцатого этапа правая и левая половины объединяются и алгоритм завершается

заключительной перестановкой (обратной по отношению к первонaчальной).














На каждом этапе биты ключа сдвигаются, и затем из 56 битов ключа выбираются 48 битов. Прaвая половина данных увеличивается до 48 битов с помощью перестановки с расширением, объединяется п o-средством XOR с 48 битами смещенного и переставленного ключа, проходит через 8 S-блоков, образуя 32 нoвых бита, и переставляется снова. Эти четыре операции и выполняются функцией f. Затем результат функции f объединяется с левой половиной с помощью другого XOR. В итоге этих действий появляется новая правая пoловина, а старая правая половина становится новой левой. Эти действия повторяются 16 раз, образуя 16 этапов

Если Вi - это результат i-ой итерации, Li и Ri - левая и правая половины Bi Ki - 48-битовый ключ для этапа i, a f - это функция, выполняющие все подстановки, перестановки и XOR с ключом, то этап можно представить как:


Li = Ri-1 =Li-1Å f(Ri-1,Ki)


Начальная перестановка


Начальная перестановка выполняется еще до этапа 1, при этом входной блок переставляется, как показано в 11-й. Эту и все другие таблицы этой главы надо читать слева направо и сверху вниз. Например, начальная пер eстановка перемещает бит 58 в битовую позицию 1, бит 50 - в битовую позицию 2, бит 42 - в битовую позицию 3, и так далее.


Начальная перестановка

58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, И, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7

Начальная перестановка и соответствующая заключительная перестановка не влияют на безопасность DES. (Как можно легко заметить, эта перестановка в первую очередь служит для облегчения побайтной загрузки данных открытого текста и шифротекста в микросхему DES. Не забывайте, что DES появился раньше 16- и 32-битовых микропроцессорных шин.) Так как программная реализация этой многобитовой перестановки нелегка (в отличие от тривиальной аппаратной), во многих программных реализациях DES начальная и заключительные перестановки не используются. Хотя такой новый алгоритм не менее безопасен, чем DES, он не соответствует стандарту DES и, поэтому, не может называться DES.


Преобразования ключа


Сначала 64-битовый ключ DES уменьшается до 56-битового ключа отбрасыванием каждого восьмого бита, как показано в 10-й. Эти биты используются только для контроля четности, позволяя проверять правильность ключа. После извлечения 56-битового ключа для каждого из 16 этапов DES генерируется новый 48-битовый подключ. Эти подключи, Ki определяются следующим образом.

Перестановка ключа


57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4

Во первых, 56-битовый ключ делится на две 28-битовых половинки. Затем, половинки циклически сдвигaются налево на один или два бита в зависимости от этапа. Этот сдвиг показан в 9-й.


Число битов сдвига ключа в зависимости от этапа

Этап 12345678910111213141516Число1122222212222221

После сдвига выбирается 48 из 56 битов. Так как при этом не только выбирается подмножество битов, но и изменяется их порядок, эта операция называется перестановка со сжатием. Ее результатом является набор из 48 битов. Перестановка со сжатием (также называемая переставленным выбором) определена в 8-й. Например, бит сдвинутого ключа в позиции 33 перемещается в позицию 35 результата, а 18-й бит сдвинутого ключа отборaсывается.


Перестановка со сжатием

14, 17, 11, 2,4, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 11, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 Из-за сдвига для каждого подключа используется отличное подмножество битов ключа. Каждый бит используется приблизительно в 14 из 16 подключей, хотя не все биты используются в точности одинаковое число раз.

Перестановка с расширением

Эта операция расширяет правую половину данных, Ri от 32 до 48 битов. Так как при этом не просто повторяются определенные биты, но и изменяется их порядок, эта операция называется перестановкой с расширением. У нее две задачи: привести размер правой половины в соответствие с ключом для операции XOR и полyчить более длинный результат, который можно будет сжать в ходе операции подстановки. Однако главный криптографический смысл совсем в другом. За счет влияния одного бита на две подстановки быстрее возрастает зависимость битов результата от битов исходных данных. Это называется лавинным эффектом. DES спроектирован так, чтобы как можно быстрее добиться зависимости каждого бита шифротекста от каждого бита открытого текста и каждого бита ключа.










Перестановка с расширением показана на 6- ом рисунке. Иногда она называется Е-блоком (от expansion). Для каждого 4-битового входного блока первый и четвертый бит представляют собой два бита выходного блока, а второй и третий биты - один бит выходного блока. В 7-й показано, какие позиции результата соответствуют каким поз и-циям исходных данных. Например, бит входного блока в позиции 3 переместится в позицию 4 выходного блока, а бит входного блока в позиции 21 - в позиции 30 и 32 выходного блока.

Хотя выходной блок больше входного, каждый входной блок генерирует уникальный выходной блок.


Перестановка с расширением

32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12., 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1

Подстановка с помощью S-блоков

После объединения сжатого блока с расширенным блоком с помощью XOR над 48-битовым результатом выполняется операция подстановки. Подстановки производятся в восьми блоках подстановки, или S-блоках (от substitution). У каждого S-блока 6-битовый вход и 4-битовый выход, всего используется восемь различных S-блоков. (Для восьми S-блоков DES потребуется 256 байтов памяти.) 48 битов делятся на восемь 6-битовых подблока. Каждый отдельный подблок обрабатывается отдельным S-блоком: первый подблок - S-блоком 1, втoрой - S-блоком 2, и так далее.




Каждый S-блок представляет собой таблицу из 2 строк и 16 столбцов. Каждый элемент в блоке является 4-битовым числом. По 6 входным битам S-блока определяется, под какими номерами столбцов и строк искать выходное значение. Все восемь S-блоков показаны в 6-й.


Входные биты особым образом определяют элемент S-блока. Рассмотрим 6-битовый вход S-блока: b1, b2, b3, b4 b5 и b6. Биты b1 и b6, объединяются, образуя 2-битовое число от 0 до 3, соответствующее строке таблицы. Средние 4 бита, с b2 по b5, объединяются, образуя 4-битовое число от 0 до 15, соответствующее столбцу таблицы.

Например, пусть на вход шестого S-блока (т.е., биты функции XOR с 31 по 36) попадает 110011. Первый и последний бит, объединяясь, образуют 11, что соответствует строке 3 шестого S-блока. Средние 4 бита образyют 1001, что соответствует столбцу 9 того же S-блока. Элемент S-блока 6, находящийся на пересечении строки 3 и столбца 9, - это 14. (Не забывайте, что строки и столбцы нумеруются с 0, а не с 1.) Вместо 110011 подставляется 1110.

Конечно же, намного легче реализовать S-блоки программно в виде массивов с 64 элементами. Для этого потребуется переупорядочить элементы, что не является трудной задачей. Изменить индексы, не изменяя порядок элементов, недостаточно. S-блоки спроектированы очень тщательно. Однако такой способ описания S-блоков помогает понять, как они работают. Каждый S-блок можно рассматривать как функцию подстановки 4-битового элемента: b2 по b5 являются входом, а некоторое 4-битовое число - результатом. Биты b1 и b6 определяются соседними блоками, они определяют одну из четырех функций подстановки, возможных в данном S-блоке.

Подстановка с помощью S-блоков является ключевым этапом DES. Другие действия алгоритма линейны и легко поддаются анализу. S-блоки нелинейны, и именно они в большей степени, чем все остальное, обеспечивают безопасность DES.

В результате этого этапа подстановки получаются восемь 4-битовых блоков, которые вновь объединяются в единый 32-битовый блок. Этот блок поступает на вход следующего этапа - перестановки с помощью Р-блоков.

Перестановка с помощью Р-блоков

-битовый выход подстановки с помощью S-блоков, перетасовываются в соответствии с Р-блоком. Эта пeрестановка перемещает каждый входной бит в другую позицию, ни один бит не используется дважды, и ни один бит не игнорируется. Этот процесс называется прямой перестановкой или просто перестановкой. Позиции, в которые перемещаются биты, показаны в нижеслеюующей таблице. Например, бит 21 перемещается в позицию 4, а бит 4 - в позицию 31.


Перестановка с помощью Р-блоков

16720212912281152326518311028241432273919133062211425

Наконец, результат перестановки с помощью Р-блока объединяется посредством XOR с левой половиной первоначального 64-битового блока. Затем левая и правая половины меняются местами, и начинается следующий этап.


Заключительная перестановка


Заключительная перестановка является обратной по отношению к начальной перестановке. Обратите внимание, что левая и правая половины не меняются местами после последнего этапа DES, вместо этого объединенный блок R16L16 используется как вход заключительной перестановки. В этом нет ничего осoбенного, перестановка половинок с последующим циклическим сдвигом привела бы к точно такому же результату. Это сделано для того, чтобы алгоритм можно было использовать как для шифрования, так и для дешифрирования.


Заключительная перестановка


40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25

Дешифрирование DES


После всех подстановок, перестановок, операций XOR и циклических сдвигов можно подумать, что алгoритм дешифрирования, резко отличаясь от алгоритма шифрования, точно также запутан. Напротив, различные компоненты DES были подобраны так, чтобы выполнялось очень полезное свойство: для шифрования и дешифрирования используется один и тот же алгоритм.

DES позволяет использовать для шифрования или дешифрирования блока одну и ту же функцию. Единственное отличие состоит в том, что ключи должны использоваться в обратном порядке. To есть, если на этапах шифрования использовались ключи K1, К2, К3, ..., K16, то ключами дешифрирования будут K16, Kl5, K14, ..., K1. Алгоритм, который создает ключ для каждого этапа, также цикличен. Ключ сдвигается направо, а число позиций сдвига равно 0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1.


Безопасность DES


Люди давно интересуются безопасностью DES. Было много рассуждений о длине ключа, количестве итераций и схеме S-блоков. S-блоки были наиболее таинственными - какие-то константы, без видимого объяcнения для чего и зачем они нужны. Хотя IBM утверждала, что работа алгоритма была результатом 17 человеко-лет интенсивного криптоанализа, некоторые люди опасались, что АНБ вставило в алгоритм лазейку, которая позволит агентству легко дешифрировать перехваченные cooбщения.

Комитет по разведке Сената США чрезвычайно тщательно расследовал этот вопрос в 1978 году. Результаты работы комитета были засекречены, но в открытых итогах этого расследования с АНБ были сняты все обвинeния в неуместном вмешательстве в проектирование алгоритма . "Было сказано, что АНБ убедило IBM в достаточности более короткого ключа, косвенно помогло разработать структуры S-блоков и подтвердило, что в окончательном варианте DES, с учетом всех знаний АНБ, отсутствовали статистические или математические бреши". Однако, так как правительство не опубликовало подробности расследования, многих людей убeдить не удалось.

С другой стороны, Копперсмит писал: "Агентство национальной безопасности также помoгало IBM техническими советами." А Конхейм (Konheim) утверждал: "Мы послали S-блоки в Вашингтон. Они вернулись полностью переработанными. Мы проверили их, и они прошли нашу проверку." На этот факт и ccылаются как на доказательство, что АНБ вставило лазейку в DES.

Тогда почему они изменили S-блоки? Может быть, чтобы гарантировать, что лазейка не будет встроена в DES самой IBM. У АНБ не было причин доверять исследователям IBM, и оно могло решить, что не до конца исполнит свой долг, если не обеспечит отсутствие лазеек в DES. Задание S-блоков и могло быть одним из спoсобов гарантировать это.

Совсем недавно новые результаты криптоанализа прояснили этот вопрос, который в течение многих лет был предметом спекуляций.


Слабые ключи


Из-за того, что первоначальный ключ изменяется при получении подключа для каждого этапа алгоритма, определенные первоначальные ключи являются слабыми. Вспомните, первоначальное значение расщепляется на две половины, каждая из которых сдвигается независимо. Если все биты каждой половины равны 0 или 1, то для всех этапов алгоритма используется один и тот же ключ. Это может произойти, если ключ состоит из одних 1, из одних 0, или если одна половина ключа состоит из одних 1, а другая - из одних 0. Кроме того, два слабых ключа обладают другими свойствами, снижающими их безопасность .


Слабые ключи DES

Значение слабого ключаДействительный ключ 0101 0101 0101 0101 0000000 0000000 1F1F 1F1F ОЕОЕ ОЕОЕ 0000000 FFFFFFF ЕОЕО ЕОЕО F1F1 F1F1 FFFFFFF 0000000 FEFE FEFE FEFE FEFE FFFFFFF FFFFFFF

Кроме того, некоторые пары ключей при шифровании переводят открытый текст в идентичный шифротекст. Иными словами, один из ключей пары может расшифровать сообщения, зашифрованные другим ключом пары. Это происходит из-за метода, используемого DES для генерации подключей - вместо 16 различных подключей эти ключи генерируют только два различных подключа. В алгоритме каждый из этих подключей используется восемь раз. Эти ключи, называемые полуслабыми ключами, в шестнадцатеричном виде приведены ниже.


Полуслабые пары ключей DES

01FE 01FE 01FE 01FE и FE01 FE01 FE01 FE01 1FEO 1FEO OEF1 OEF1 и E01F E01F F10E F10E 01ЕО 01ЕО 01F1 01F1 и Е001 Е001 F101 F101 1FFE IEEE OEFE OEFE и FE1F FE1F FEOE FEOE 01 IF 011F 010Е 010E и 1F01 1F01 ОЕ01 ОЕ01 EOFE EOFE FIFE FIFE и FEEO FEEO FEE1 FEE1

Ряд ключей генерирует только четыре подключа, каждый из которых четыре раза используется в алгоритме.


Эти возможно слабые ключи перечислены таблице.


Возможно слабые ключи DES

IF IF 01 01 ОЕ ОЕ 01 01 ЕО 01 01 ЕО F1 01 01 F1 01 IF IF 01 01 ОЕ ОЕ 01 FE IF 01 ЕО FE ОЕ 01 F1 IF 01 01 IF ОЕ 01 01 ОЕ FE 01 IF ЕО FE 01 ОЕ F1 01 01 IF IF 01 01 ОЕ ОЕ ЕО IF IF ЕО F1 ОЕ ОЕ F1 ЕО ЕО 01 01 F1 F1 01 01 FE 01 01 FE FE 01 01 FE FE FE 01 01 FE FE 01 01 ЕО IF 01 FE F1 ОЕ 01 FE FE ЕО IF 01 FE F1 ОЕ 01 ЕО 01 IF FE F1 01 ОЕ FE ЕО FE IF 01 F1 FE ОЕ 01 FE IF IF FE FE ОЕ ОЕ FE FE ЕО 01 IF FE F1 01 ОЕ IF FE 01 ЕО ОЕ FE 01 F1 ЕО FE 01 IF F1 FE 01 ОЕ 01 FE IF ЕО 01 FE ОЕ F1 ЕО ЕО IF IF F1 F1 ОЕ ОЕ IF ЕО 01 FE ОЕ F1 01 FE FE FE IF IF FE FE ОЕ ОЕ 01 ЕО IF FE 01 F1 ОЕ FE FE IF ЕО 01 FE ОЕ F1 01 01 01 ЕО ЕО 01 01 F1 F1 ЕО IF FE 01 F1 ОЕ FE 01 IF IF ЕО ЕО ОЕ ОЕ F1 F1 FE 01 ЕО IF FE 01 F1 ОЕ IF 01 FE ЕО ОЕ 01 FE F1 ЕО 01 FE IF F1 01 FE ОЕ 01 IF FE ЕО 01 ОЕ FE F1 01 ЕО ЕО 01 01 F1 F1 01 IF 01 ЕО FE ОЕ 01 F1 FE IF FE ЕО 01 ОЕ FE FO 01 01 IF ЕО FE 01 ОЕ F1 FE IF ЕО FE 01 ОЕ F1 FE 01 01 01 FE FE 01 01 FE FE 01 FE FE 01 01 FE FE 01 IF IF FE FE ОЕ ОЕ FE FE IF ЕО ЕО IF ОЕ F1 F1 ОЕ FE FE ЕО ЕО FE FE F1 F1 01 FE ЕО IF 01 FE F1 ОЕ ЕО FE FE ЕО F1 FE FE F1 01 ЕО FE IF 01 F1 FE ОЕ FE ЕО ЕО FE FE F1 F1 FE IF FE FE IF ОЕ FE FE ОЕ ЕО ЕО FE FE F1 F1 FE FE

Прежде, чем порицать DES слабые ключи, обратите внимание на то, что эти 64 ключа - это крошечная часть полного набора из 72057594037927936 возможных ключей. Если вы выбираете ключ случайно, вероятность выбрать один из слабых ключей пренебрежимо мала. Если вы настоящий параноик, можете всегда проверять "на слабость" сгенерированный ключ. Некоторые думают, что нечего и беспокоиться на этот счет. Другие утверждают, что проверка очень легка, почему бы ее и не выполнить.

Дальнейший анализ слабых и полуслабых ключей приведен в. Других слабых ключей в процессе иcследований найдено не было.

Теперь, пожалуй можно приступить к описанию другого довольно популярного стандарта шифрованиея-ГОСТ. Вы конечно можите спросить- а почему не к AES? Да всё довольно просто- дело в том что буквально на днях, АНБ, в связи с войной в Ираке пересмотрело недавно ими же одобренный стандарт AES- и пришло к выводу что алгоритм недостаточно хорош…. Было решено найти новый, более устойчивый алгоритм.. Единственный алгоритм который удовлетворил требованиям оказался…. ГОСТ 28147-89! Так что в обозримом будущем именно ГОСТ станет новым национальным стандартом шифрования США. Называться он скорее всего будет по другому- но это уже другая история…

Я решил что описывать AES не стоит- не выдержал главного- испытание временем

Единственное что я замечу- обозначения отличаются от предыдущих- ибо ГОСТ описан не русском, неплохо, и менять что-либо опасно- всё-таки это фактически выдержки из официального документа.


Логика построения шифра и структура ключевой информации ГОСТа


Если внимательно изучить оригинал ГОСТа 28147-89, можно заметить, что в нем содержится описание алгоритмов нескольких уровней. На самом верхнем находятся практические алгоритмы, предназначенные для шифрования массивов данных и выработки для них имитовставки. Все они опираются на три алгоритма низшего уровня, называемые в тексте ГОСТа циклами. Эти фундаментальные алгоритмы упоминаются в как базовые циклы, чтобы отличать их от всех прочих циклов. Они имеют следующие названия и обозначения, последние приведены в скобках и смысл их будет объяснен позже:

  1. цикл зашифрования (32-З);
  2. цикл расшифрования (32-Р);
  3. цикл выработки имитовставки (16-З).

В свою очередь, каждый из базовых циклов представляет собой многократное повторение одной единственной процедуры, называемой для определенности далее в настоящей работе основным шагом криптопреобразования.

Таким образом, чтобы разобраться в ГОСТе, надо понять три следующие вещи:

а) что такое основной шаг криптопреобразования;

б) как из основных шагов складываются базовые циклы;

в) как из трех базовых циклов складываются все практические алгоритмы ГОСТа.

В ГОСТе ключевая информация состоит из двух структур данных. Помимо собственно ключа, необходимого для всех шифров, она содержит еще и таблицу замен. Ниже приведены основные характеристики ключевых структур ГОСТа.

Ключ является массивом из восьми 32-битных элементов кода, далее в настоящей работе он обозначается символом К:. В ГОСТе элементы ключа используются как 32-разрядные целые числа без знака: . Таким образом, размер ключа составляет 32·8=256 бит или 32 байта.

Таблица замен является матрицей 8´16, содержащей 4-битовые элементы, которые можно представить в виде целых чисел от 0 до 15. Строки таблицы замен называются узлами замен, они должны содержать различные значения, то есть каждый узел замен должен содержать 16 различных чисел от 0 до 15 в произвольном порядке. В настоящей статье таблица замен обозначается символом H: . Таким образом, общий объем таблицы замен равен: 8 узлов ´ 16 элементов/узел ´ 4 бита/элемент = 512 бит или 64 байта.


Основной шаг криптопреобразования


Основной шаг криптопреобразования по своей сути является оператором, определяющим преобразование 64-битового блока данных. Дополнительным параметром этого оператора является 32-битовый блок, в качестве которого используется какой-либо элемент ключа. Схема алгоритма основного шага приведена на рисунке. Ниже даны пояснения к алгоритму основного шага:

  1. Определяет исходные данные для основного шага криптопреобразования:

N-преобразуемый 64-битовый блок данных, в ходе выполнения шага его младшая

(N1) и старшая (N2) части обрабатываются как отдельные 32-битовые целые числа без знака.

Таким образом, можно записать N=(N1,N2).X-32-битовый элемент ключа;

  1. Сложение с ключом. Младшая половина преобразуемого блока складывается по модулю 232 с используемым на шаге элементом ключа, результат передается на следующий шаг;
  2. Поблочная замена. 32-битовое значение, полученное на предыдущем шаге, интерпретируется как массив из восьми 4-битовых блоков кода: S=(S0,S1,S2,S3,S4,S5,S6,S7).

Далее значение каждого из восьми блоков заменяется на новое, которое выбирается по таблице замен следующим образом: значение блока Si заменяется на Si-тый по порядку элемент (нумерация с нуля) i-того узла замен (т.е. i-той строки таблицы замен, нумерация также с нуля). Другими словами, в качестве замены для значения блока выбирается элемент из таблицы замен с номером строки, равным номеру заменяемого блока, и номером столбца, равным значению заменяемого блока как 4-битового целого неотрицательного числа. Теперь становится понятным размер таблицы замен: число строк в ней равно числу 4-битных элементов в 32-битном блоке данных, то есть восьми, а число столбцов равно числу различных значений 4-битного блока данных, равному как известно 24, шестнадцати.


Схема основного шага криптопреобразования алгоритма ГОСТ 28147.

  1. Циклический сдвиг на 11 бит влево. Результат предыдущего шага сдвигается циклически на 11 бит в сторону старших разрядов и передается на следующий шаг. На схеме алгоритма символом ?11 обозначена функция циклического сдвига своего аргумента на 11 бит в сторону старших разрядов.
  2. Побитовое сложение: значение, полученное на шаге 3, побитно складывается по модулю 2 со старшей половиной преобразуемого блока.
  3. Сдвиг по цепочке: младшая часть преобразуемого блока сдвигается на место старшей, а на ее место помещается результат выполнения предыдущего шага.
  4. Полученное значение преобразуемого блока возвращается как результат выполнения алгоритма основного шага криптопреобразования.

Базовые циклы криптографических преобразований


Базовые циклы построены из основных шагов криптографического преобразования, рассмотренного в предыдущем разделе. В процессе выполнения основного шага используется только один элемент ключа, в то время как ключ ГОСТ содержит восемь таких элементов. Следовательно, чтобы ключ был использован полностью, каждый из базовых циклов должен многократно выполнять основной шаг с различными его элементами. Вместе с тем кажется вполне естественным, что в каждом базовом цикле все элементы ключа должны быть использованы одинаковое число раз, по соображениям стойкости шифра это число должно быть больше одного.

Все сделанные выше предположения, опирающиеся просто на здравый смысл, оказались верными. Базовые циклы заключаются в многократном выполнении основного шага с использованием разных элементов ключа и отличаются друг от друга только числом повторения шага и порядком использования ключевых элементов. Ниже приведен этот порядок для различных циклов.

  1. Цикл зашифрования 32-З:

K0,K1,K2,K3,K4,K5,K6,K7,K0,K1,K2,K3,K4,K5,K6,K7,K0,K1,K2,K3,K4,K5,K6,K7,K7,K6,K5,K4,K3,K2,K1,K0.

  1. Цикл расшифрования 32-Р: K0,K1,K2,K3,K4,K5,K6,K7,K7,K6,K5,K4,K3,K2,K1,K0,K7,K6,K5,K4,K3,K2,K1,K0,K7,K6,K5,K4,K3,K2,K1,K0.
  2. Цикл выработки имитовставки 16-З:

K0,K1,K2,K3,K4,K5,K6,K7,K0,K1,K2,K3,K4,K5,K6,K7.

Каждый из циклов имеет собственное буквенно-цифровое обозначение, соответствующее шаблону «n-X», где первый элемент обозначения (n), задает число повторений основного шага в цикле, а второй элемент обозначения (X), буква, задает порядок зашифрования («З») или расшифрования («Р») в использовании ключевых элементов. Этот порядок нуждается в дополнительном пояснении:

Цикл расшифрования должен быть обратным циклу зашифрования, то есть последовательное применение этих двух циклов к произвольному блоку должно дать в итоге исходный блок, что отражается следующим соотношением:


Ц32-Р(Ц32-З(T))=T,

где T - произвольный 64-битный блок данных, ЦX(T) - результат выполнения цикла X над блоком данных T.


Для выполнения этого условия для алгоритмов, подобных ГОСТу, необходимо и достаточно, чтобы порядок использования ключевых элементов соответствующими циклами был взаимно обратным. В справедливости записанного условия для рассматриваемого случая легко убедиться, сравнив приведенные выше последовательности для циклов 32-З è 32-Р. Из сказанного вытекает одно интересное следствие: свойство цикла быть обратным другому циклу является взаимным, то есть цикл 32-З является обратным по отношению к циклу 32-Р (В пришципе так работает почти любой блочный алгоритм- в DES мы уже это видели) . Другими словами, зашифрование блока данных теоретически может быть выполнено с помощью цикла расшифрования, в этом случае расшифрование блока данных должно быть выполнено циклом зашифрования. Из двух взаимно обратных циклов любой может быть использован для зашифрования, тогда второй должен быть использован для расшифрования данных, однако стандарт закрепляет роли за циклами и не предоставляет пользователю права выбора в этом вопросе.


Схема цикла зашифрования 32-З. Схема цикла расшифрования 32-Р.

Цикл выработки имитовставки вдвое короче циклов шифрования, порядок использования ключевых элементов в нем такой же, как в первых 16 шагах цикла зашифрования, в чем нетрудно убедиться, рассмотрев приведенные выше последовательности, поэтому этот порядок в обозначении цикла кодируется той же самой буквой «З».


Схема цикла выработки имитовставки 16-З.


Схемы базовых циклов приведены на рисунках 2а-в. Каждый из них принимает в качестве аргумента и возвращает в качестве результата 64-битный блок данных, обозначенный на схемах N. Символ Шàã(N,X) обозначает выполнение основного шага криптопреобразования для блока N с использованием ключевого элемента X. Между циклами шифрования и вычисления имитовставки есть еще одно отличие, не упомянутое выше: в конце базовых циклов шифрования старшая и младшая часть блока результата меняются местами, это необходимо для их взаимной обратимости.


Основные режимы шифрования


ГОСТ предусматривает три следующих режима шифрования данных:

  1. простая замена,
  2. гаммирование,
  3. гаммирование с обратной связью,

и один дополнительный режим выработки имитовставки.

В любом из этих режимов данные обрабатываются блоками по 64 бита, на которые разбивается массив, подвергаемый криптографическому преобразованию, именно поэтому ГОСТ относится к блочным шифрам. Однако в двух режимах гаммирования есть возможность обработки неполного блока данных размером меньше 8 байт, что существенно при шифровании массивов данных с произвольным размером, который может быть не кратным 8 байтам.

Прежде чем перейти к рассмотрению конкретных алгоритмов криптографических преобразований, необходимо пояснить обозначения, используемые на схемах в следующих разделах:


Tо,Tш - массивы соответственно открытых и зашифрованных данных;

,- i-тые по порядку 64-битные блоки соответственно открытых и зашифрованных данных:, , ??i?n, последний блок может быть неполным: ;

n-число 64-битных блоков в массиве данных;

ЦX-функция преобразования 64-битного блока данных по алгоритму базового цикла «X»;

Опишем основные режимы шифрования:


Простая замена


Зашифрование в данном режиме заключается в применении цикла 32-З к блокам открытых данных, расшифрование - цикла 32-Р к блокам зашифрованных данных. Это наиболее простой из режимов, 64-битовые блоки данных обрабатываются в нем независимо друг от друга. Схемы алгоритмов зашифрования и расшифрования в режиме простой замены приведены на рисунках 3а и б соответственно, они тривиальны и не нуждаются в комментариях.

Размер массива открытых или зашифрованных данных, подвергающийся соответственно зашифрованию или расшифрованию, должен быть кратен 64 битам: |Tо|=|Tш|=64·n, после выполнения операции размер полученного массива данных не изменяется.



Алгоритм зашифрования данных в режиме простой замены.



Алгоритм расшифрования данных в режиме простой замены.

Режим шифрования простой заменой имеет следующие особенности:

  1. Так как блоки данных шифруются независимо друг от друга и от их позиции в массиве, при зашифровании двух одинаковых блоков открытого текста получаются одинаковые блоки шифротекста и наоборот. Отмеченное свойство позволит криптоаналитику сделать заключение о тождественности блоков исходных данных, если в массиве зашифрованных данных ему встретились идентичные блоки, что является недопустимым для серьезного шифра.
  2. Если длина шифруемого массива данных не кратна 8 байтам или 64 битам, возникает проблема, чем и как дополнять последний неполный блок данных массива до полных 64 бит. Эта задача не так проста, как кажется на первый взгляд, поскольку очевидные решения типа «дополнить неполный блок нулевыми битами» или, более обще, «дополнить неполный блок фиксированной комбинацией нулевых и единичных битов» могут при определенных условиях дать в руки криптоаналитика возможность методами перебора определить содержимое этого самого неполного блока, и этот факт означает снижение стойкости шифра. Кроме того, длина шифротекста при этом изменится, увеличившись до ближайшего целого, кратного 64 битам, что часто бывает нежелательным.

На первый взгляд, перечисленные выше особенности делают практически невозможным использование режима простой замены, ведь он может применяться только для шифрования массивов данных с размером кратным 64 битам, не содержащим повторяющихся 64-битных блоков. Кажется, что для любых реальных данных гарантировать выполнение указанных условий невозможно. Это почти так, но есть одно очень важное исключение: вспомните, что размер ключа составляет 32 байта, а размер таблицы замен - 64 байта. Кроме того, наличие повторяющихся 8-байтовых блоков в ключе или таблице замен будет говорить об их весьма плохом качестве, поэтому в реальных ключевых элементах такого повторения быть не может. Таким образом мы выяснили, что режим простой замены вполне подходит для шифрования ключевой информации, тем более, что прочие режимы для этой цели менее удобны, поскольку требуют наличия дополнительного синхронизирующего элемента данных - синхропосылки. Догадка верна, ГОСТ предписывает использовать режим простой замены исключительно для шифрования ключевых данных.

Гаммирование


Как же можно избавиться от недостатков режима простой замены? Для этого необходимо сделать возможным шифрование блоков с размером менее 64 бит и обеспечить зависимость блока шифротекста от его номера, иными словами, рандомизировать процесс шифрования. В ГОСТе это достигается двумя различными способами в двух режимах шифрования, предусматривающих гаммирование. Гаммирование - это наложение (снятие) на открытые (зашифрованные) данные криптографической гаммы, то есть последовательности элементов данных, вырабатываемых с помощью некоторого криптографического алгоритма, для получения зашифрованных (открытых) данных. Для наложения гаммы при зашифровании и ее снятия при расшифровании должны использоваться взаимно обратные бинарные операции, например, сложение и вычитание по модулю 264 для 64-битных блоков данных. В ГОСТе для этой цели используется операция побитного сложения по модулю 2, поскольку она является обратной самой себе и к тому же наиболее просто реализуется. Гаммирование решает обе упомянутые проблемы; во первых, все элементы гаммы различны для реальных шифруемых массивов и, следовательно, результат зашифрования даже двух одинаковых блоков в одном массиве данных будет различным. Во вторых, хотя элементы гаммы и вырабатываются одинаковыми порциями в 64 бита, использоваться может и часть такого блока с размером, равным размеру шифруемого блока.

Теперь перейдем непосредственно к описанию режима гаммирования. Гамма для этого режима получается следующим образом: с помощью некоторого алгоритмического Рекуррентного Генератора Последовательности Чисел (РГПЧ) вырабатываются 64-битные блоки данных, которые далее подвергаются преобразованию по циклу 32-З, то есть зашифрованию в режиме простой замены, в результате получаются блоки гаммы. Благодаря тому, что наложение и снятие гаммы осуществляется при помощи одной и той же операции побитового исключающего или, алгоритмы зашифрования и расшифрования в режиме гаммирования идентичны.

РГПЧ, используемый для выработки гаммы, является рекуррентной функцией: ?i+1=f(?i), где ?i - элементы рекуррентной последовательности, f - функция преобразования. Следовательно, неизбежно возникает вопрос о его инициализации, то есть об элементе ?0. В действительности, этот элемент данных является параметром алгоритма для режимов гаммирования, на схемах он обозначен как S, и называется в криптографии синхропосылкой, а в нашем ГОСТе - начальным заполнением одного из регистров шифрователя. По определенным соображениям разработчики ГОСТа решили использовать для инициализации РГПЧ не непосредственно синхропосылку, а результат ее преобразования по циклу 32-З: ?032-З(S). Последовательность элементов, вырабатываемых РГПЧ, целиком зависит от его начального заполнения, то есть элементы этой последовательности являются функцией своего номера и начального заполнения РГПЧ: ?i=fi(?0), где fi(X)=f(fi-1(X)), f0(X)=X. С учетом преобразования по алгоритму простой замены добавляется еще и зависимость от ключа:


Гi32-З(?i)=Ц32-З(fi(?0))=Ц32-З(fi32-З(S)))=?i(S,K),


где Гi - i-тый элемент гаммы, K - ключ.


Таким образом, последовательность элементов гаммы для использования в режиме гаммирования однозначно определяется ключевыми данными и синхропосылкой. Естественно, для обратимости процедуры шифрования в процессах за- и расшифрования должна использоваться одна и та же синхропосылка. Из требования уникальности гаммы, невыполнение которого приводит к катастрофическому снижению стойкости шифра, следует, что для шифрования двух различных массивов данных на одном ключе необходимо обеспечить использование различных синхропосылок. Это приводит к необходимости хранить или передавать синхропосылку по каналам связи вместе с зашифрованными данными, хотя в отдельных особых случаях она может быть предопределена или вычисляться особым образом, если исключается шифрование двух массивов на одном ключе.

Схема алгоритма шифрования в режиме гаммирования приведена на рисунке ниже и изложены пояснения к схеме:



Алгоритм зашифрования (расшифрования) данных в режиме гаммирования.

1)Определяет исходные данные для основного шага криптопреобразования:

  • Tо(ш)-массив открытых (зашифрованных) данных произвольного размера, подвергаемый процедуре зашифрования (расшифрования), по ходу процедуры массив подвергается преобразованию порциями по 64 бита;
  • S-синхропосылка, 64-битный элемент данных, необходимый для инициализации генератора гаммы;

2)Начальное преобразование синхропосылки, выполняемое для ее «рандомизации», то есть для устранения статистических закономерностей, присутствующих в ней, результат используется как начальное заполнение РГПЧ;

3)Один шаг работы РГПЧ, реализующий его рекуррентный алгоритм. В ходе данного шага старшая (S1) и младшая (S0) части последовательности данных вырабатываются независимо друг от друга;

)Гаммирование. Очередной 64-битный элемент, выработанный РГПЧ, подвергается процедуре зашифрования по циклу 32-З, результат используется как элемент гаммы для зашифрования (расшифрования) очередного блока открытых (зашифрованных) данных того же размера.

)Результат работы алгоритма - зашифрованный (расшифрованный) массив данных.

Ниже перечислены особенности гаммирования как режима шифрования.

  1. Одинаковые блоки в открытом массиве данных дадут при зашифровании различные блоки шифротекста, что позволит скрыть факт их идентичности.
  2. Поскольку наложение гаммы выполняется побитно, шифрование неполного блока данных легко выполнимо как шифрование битов этого неполного блока, для чего используется соответствующие биты блока гаммы. Так, для зашифрования неполного блока в 1 бит можно использовать любой бит из блока гаммы.
  3. Синхропосылка, использованная при зашифровании, каким-то образом должна быть передана для использования при расшифровании. Это может быть достигнуто следующими путями:
  4. хранить или передавать синхропосылку вместе с зашифрованным массивом данных, что приведет к увеличению размера массива данных при зашифровании на размер синхропосылки, то есть на 8 байт;
  5. использовать предопределенное значение синхропосылки или вырабатывать ее синхронно источником и приемником по определенному закону, в этом случае изменение размера передаваемого или хранимого массива данных отсутствует;

Оба способа дополняют друг друга, и в тех редких случаях, где не работает первый, наиболее употребительный из них, может быть использован второй, более экзотический. Второй способ имеет гораздо меньшее применение, поскольку сделать синхропосылку предопределенной можно только в том случае, если на данном комплекте ключевой информации шифруется заведомо не более одного массива данных, что бывает в редких случаях. Генерировать синхропосылку синхронно у источника и получателя массива данных также не всегда представляется возможным, поскольку требует жесткой привязки к чему-либо в системе. Так, здравая на первый взгляд идея использовать в качестве синхропосылки в системе передачи зашифрованных сообщений номер передаваемого сообщения не подходит, поскольку сообщение может потеряться и не дойти до адресата, в этом случае произойдет десинхронизация систем шифрования источника и приемника. Поэтому в рассмотренном случае нет альтернативы передаче синхропосылки вместе с зашифрованным сообщением.

С другой стороны, можно привести и обратный пример. Допустим, шифрование данных используется для защиты информации на диске, и реализовано оно на низком уровне, для обеспечения независимого доступа данные шифруются по секторам. В этом случае невозможно хранить синхропосылку вместе с зашифрованными данными, поскольку размер сектора нельзя изменить, однако ее можно вычислять как некоторую функцию от номера считывающей головки диска, номера дорожки (цилиндра) и номера сектора на дорожке. В этом случае синхропосылка привязывается к положению сектора на диске, которое вряд ли может измениться без переформатирования диска, то есть без уничтожения данных на нем.

Режим гаммирования имеет еще одну интересную особенность. В этом режиме биты массива данных шифруются независимо друг от друга. Таким образом, каждый бит шифротекста зависит от соответствующего бита открытого текста и, естественно, порядкового номера бита в массиве: . Из этого вытекает, что изменение бита шифротекста на противоположное значение приведет к аналогичному изменению бита открытого текста на противоположный:


,


где обозначает инвертированное по отношению к t значение бита ().


Выработка имитовставки к массиву данных


Выше мы обсудили влияние искажения шифрованных данных на соответствующие открытые данные. Мы установили, что при расшифровании в режиме простой замены соответствующий блок открытых данных оказывается искаженным непредсказуемым образом, а при расшифровании блока в режиме гаммирования изменения предсказуемы. В режиме гаммирования с обратной связью искаженными оказываются два блока, один предсказуемым, а другой непредсказуемым образом. Значит ли это, что с точки зрения защиты от навязывания ложных данных режим гаммирования является плохим, а режимы простой замены и гаммирования с обратной связью хорошими? Ни в коем случае. При анализе данной ситуации необходимо учесть то, что непредсказуемые изменения в расшифрованном блоке данных могут быть обнаружены только в случае избыточности этих самых данных, причем чем больше степень избыточности, тем вероятнее обнаружение искажения. Очень большая избыточность имеет место, например, для текстов на естественных и искусственных языках, в этом случае факт искажения обнаруживается практически неизбежно. Однако в других случаях, например, при искажении сжатых звуковых образов, мы получим просто другой образ, который сможет воспринять наше ухо. Искажение в этом случае останется необнаруженным, если, конечно, нет априорной информации о характере звука. Вывод здесь такой: поскольку способность некоторых режимов шифрования обнаруживать искажения, внесенные в шифрованные данные, существенным образом опирается на наличие и степень избыточности шифруемых данных, эта способность не является имманентным свойством соответствующих режимов и не может рассматриваться как их достоинство.


Алгоритм выработки имитовставки для массива данных.


Для решения задачи обнаружения искажений в зашифрованном массиве данных с заданной вероятностью в ГОСТе предусмотрен дополнительный режим криптографического преобразования - выработка имитовставки. Имитовставка - это контрольная комбинация, зависящая от открытых данных и секретной ключевой информации. Целью использования имитовставки является обнаружение всех случайных или преднамеренных изменений в массиве информации. Проблема, изложенная в предыдущем пункте, может быть успешно решена с помощью добавления к шифрованным данным имитовставки. Для потенциального злоумышленника две следующие задачи практически неразрешимы, если он не владеет ключевой информацией:

  1. вычисление имитовставки для заданного открытого массива информации;
  2. подбор открытых данных под заданную имитовставку;

Схема алгоритма выработки имитовставки приведена на рисунке 6. В качестве имитовставки берется часть блока, полученного на выходе, обычно 32 его младших бита. При выборе размера имитовставки надо принимать во внимание, что вероятность успешного навязывания ложных данных равна величине 2-|И| на одну попытку подбора. При использовании имитовставки размером 32 бита эта вероятность равна 2-32?0.23·10-9.

Так ну вроде все с симметричными криптосистемами…. Два основных и наиболее испытанных стандарта разобраны. Пора бы приступить к криптографии с открытыми ключами.


RSA


Безопасность RSA основана на трудности разложения на множители больших чисел. Открытый и закрытый ключи являются функциями двух больших (100-200 разрядов или даже больше) простых чисел. Предполагается, что восстановление открытого текста по шифротексту и открытому ключу эквивалентно разложению на множители двух больших чисел .

Для генерации двух ключей используются два больших случайных простых числа , p и q. Для максимальной безопасности выбирайте p и q равной длины. Рассчитывается произведение:


n=pq

Затем случайным образом выбирается ключ шифрования e, такой что e и (p-1)(q-1) являются взаимно простыми числами. Наконец расширенный алгоритм Эвклида используется для вычисления ключа дешифрировaния d, такого что


ed=l(mod (p-l))(q-l)) Другими словами

d=e-1 mod ((p-1)(q-1))


Заметим, что d и n также взаимно простые числа. Числа e и n - это открытый ключ, а число d - закрытый. Два простых числа p и q больше не нужны. Они должны быть отброшены, но не должны быть раскрыты .

Для шифрования сообщения т оно сначала разбивается на цифровые блоки, меньшие n (для двоичных данных выбирается самая большая степень числа 2, меньшая n). To есть, если p и q - 100-разрядные простые числа, то n будет содержать около 200 разрядов, и каждый блок сообщения w, должен быть около 200 разрядов в длину. (Если нужно зашифровать фиксированное число блоков, их можно дополнить несколькими нулями слeва, чтобы гарантировать, что блоки всегда будут меньше п. Зашифрованное сообщение с будет состоять из блоков ci той же самой длины . Формула шифрования выглядит так


ci=mie mod m


Для расшифровки сообщения возьмите каждый зашифрованный блок с, и вычислите


mi = Cid mod n


Так как

ci = (mie)d = mied = mi k(p-1)(q-1)+1= mi mi k(p-1)(q-1) =mi*1

все (mod n)


формула восстанавливает сообщение.

Шифрование RSA

  • Открытый ключ:

n произведение двух простых чисел p и q (p и q должны храниться в секрете) e число, взаимно простое c (p-1)(q-1)

  • Закрытый ключ:

d e mod ((p-1)(q-1))

  • Шифрование:

с = me mod n

  • Дешифрирование:

m = cd mod n

Точно также сообщение может быть зашифровано с помощью d, а зашифровано с помощью e, возможен любой выбор.

Короткий пример возможно поможет пояснить работу алгоритма . Если p = 47 и q = 71 , то

n=pq=3337

Ключ e не должен иметь общих множителей

(p-1)(q-1)=46*70=3220

Выберем (случайно) e равным 79. B этом случае d= 79-1 mod 3220 = 1019

При вычислении этого числа использован расширенный алгоритм Эвклида. Опубликуем e и n, сохранив в секрете d. Отбросим p и q. Для шифрования сообщения

m = 6882326879666683

сначала разделим его на маленькие блоки. Для нашего случая подойдут трехбуквенные блоки . Сообщение разбивается на шесть блоков mi:

m1 = 688

m2 = 232

m3 = 687

m4 = 966

m5 = 668

m6 = 003

Первый блок шифруется как 68879 mod 3337 = 1570 = ci

Выполняя те же операции для последующих блоков, создает шифротекст сообщения :

с = 1570 2756 2091 2276 2423 158

Для дешифрирование нужно выполнить такое же возведение в степень, используя ключ дешифрирования 1019:

1019 mod 3337 = 688 = mi

Аналогично восстанавливается оставшаяся часть сообщения .


Скорость RSA


Аппаратно RSA примерно в 1000 раз медленнее DES. Скорость работы самой быстрой СБИС-реализации RSA с 512-битовым модулем - 64 килобита в секунду. Существуют также микросхемы, которые выполняют 1024-битовое шифрование RSA. B настоящее время разрабатываются микросхемы, которые, используя 512-битовый модуль, приблизятся к рубежу 1 Мбит/с. Производители также применяют RSA в интеллектуальных карточках, но эти реализации медленнее.

Программно DES примерно в 100 раз быстрее RSA. Эти числа могут незначительно измениться при изменении технологии, но RSA никогда не достигнет скорости симметричных алгоритмов . B 15-й приведены примеры скоростей программного шифрования RSA.

Скорости RSA для различных длин модулей при 8-битовом открытом ключе


512 битов768 битов1024 битаШифрование ДешифрированиПодпись Проверка0.03с 0.16с 0.16с 0.02с0.05с 0.48с 0.52с 0.07с0.08с 0.93с 0.97с 0.08с

Шифрование RSA выполняется намного быстрей, если вы правильно выберете значение e. Тремя наиболее частыми вариантами являются 3, 17 и 65537 (216 + 1). (Двоичное представление 65537 содержит только две единицы, поэтому для возведения в степень нужно выполнить только 17 умножений.) X.509 советует 65537 , PEM рекомендует 3 , a PKCS #1 - 3 или 65537 . He существует никаких проблем безопасности, связанных с использованием в качестве e любого из этих трех значений (при условии, что вы дополняете сообщения случайными числами - см. раздел ниже), даже если одно и то же значение e используется целой группой пользователей.


Безопасность RSA


Безопасность RSA полностью зависит от проблемы разложения на множители больших чисел. Технически, это утверждение о безопасности лживо. Предполагается, что безопасность RSA зависит от проблемы разложения на множители больших чисел. Никогда не было доказано математически, что нужно разложить n на множители, чтобы восстановить т по с и e. Понятно, что может быть открыт совсем иной способ криптоанализа RSA. Однако, если этот новый способ позволит криптоаналитику получить d, он также может быть использован для разложения на множители больших чисел. Я не слишком волнуюсь об этом.

Также можно вскрыть RSA, угадав значение (p-1)(q-1). Это вскрытие не проще разложения n на множители.

Для сверхскептиков: доказано, что некоторые варианты RSA также сложны, как и разложение на множители

Самым очевидным средством вскрытия является разложение n на множители. Любой противник сможет получить открытый ключ e и модуль п. Чтобы найти ключ дешифрирования d, противник должен разложить n на множители. Современное состояние технологии разложения на множители рассматривалось в разделе 11.4. B настоящее время передним краем этой технологии является число, содержащее 129 десятичных цифр . Значит, n должно быть больше этого значения. Рекомендации по выбору длины открытого ключа приведены дополнении

Конечно, криптоаналитик может перебирать все возможные d, пока он не подберет правильное значение. Ho такое вскрытие грубой силой даже менее эффективно, чем попытка разложить n на множители.

Время от времени появляются заявления о том, что найден простой способ вскрытия RSA, но пока ни одно из подобных заявлений не подтвердилось. Например, в 1993 году в черновике статьи Вильяма Пейна (William Payne) был предложен метод, основанный на малой теореме Ферма . K сожалению, (а может и по счастью) этот метод оказался медленнее разложения на множители

Существует еще один повод для беспокойства. Большинство общепринятых алгоритмов вычисления простых чисел p и q вероятностны, что произойдет, если p или q окажется составным? Hy, во первых, можно свести вероятность такого события до нужного минимума. И даже если это произойдет, скорее всего такое событие будет сразу же обнаружено - шифрование и дешифрирование не будут работать. Существует ряд чисел, называемых числами Кармайкла, которые не могут обнаружить определенные вероятностные алгоритмы поиcка простых чисел. Они небезопасны, но чрезвычайно редки. Честно говоря, меня бы это не обеспокоило.

Вскрытие с выбранным шифротекстом против RSA


Некоторые вскрытия работают против реализаций RSA. Они вскрывают не сам базовый алгоритм, а надстроенный над ним протокол. Важно понимать, что само по себе использование RSA не обеспечивает безопасности. Дело в реализации.

Сценарий 1: Е, подслушавшему линии связи А, удалось перехватить сообщение с, шифрованное с помощью RSA открытым ключом А. Е хочет прочитать сообщение. Ha языке математики, ему нужно т, для которого


т = cd


Для раскрытия т он сначала выбирает первое случайное число r, меньшее п. Она достает открытый ключ А e. Затем он вычисляет


x = re mod n = xc mod n = r-1 mod n

Если x = re mod n, то r = xdmod n.


Теперь E просит А подписать у его закрытым ключом, таким образом расшифровав у He забывайте, А никогда раньше не видел у. А посылает Е


и = yd mod n


Теперь Е вычисляет


tu mod n = r-1 yd mod = r -1xd cd mod n = cd mod n = m


И получает т.

Сценарий 2: С - это компьютер-нотариус. Если А хочет заверить документ, он посылает его С. С подписывает его цифровой подписью RSA и отправляет обратно. (Однонаправленные хэш-функции не используются, С шифрует все сообщение своим закрытым ключом .)хочет, чтобы С подписал такое сообщение, которое в обычном случае он никогда не подпишет. Может быть это фальшивая временная метка, может быть автором этого сообщения является другое лицо. Какой бы ни была причина, С никогда не подпишет это сообщение, если у него будет возможность выбора. Назовем это сообщение т'.

Сначала F выбирает произвольное значение x и вычисляет у = xe mod n. e он может получить без труда - это открытый ключ С, который должен быть опубликован, чтобы можно было проверять подписи С. Теперь F вычисляет m = ym' mod n и посылает т С на подпись. С возвращает md mod n. Теперь F вычисляет (md mod n)x-1 mod n, которое равно nd mod n и является подписью m'.

Ha самом деле F может использовать множество способов решить подобную задачу. Слабым местом, которое используют такие вскрытия, является сохранение мультипликативной структуры входа при возведении в степень. To есть:


(xm)d mod n = x d md mod n


Сценарий 3: Е хочет, чтобы А подписал m3. Он создает два сообщения, m1 и m2, такие что


m3=m1m2 mod m


Если Ева сможет заставить А подписать m1 и m2, она может вычислить подпись для m3:

M3d =(m1d mod n)(m2d mod n)


Мораль: Никогда не пользуйтесь алгоритмом RSA для подписи случайных документов, подсунутых вам посторонними. Всегда сначала воспользуйтесь однонаправленной хэш-фунцией.


Вскрытие общего модуля RSA


При реализации RSA можно попробовать раздать всем пользователям одинаковый модуль и, но каждому свои значения показателей степени e и d. K сожалению, это не работает. Наиболее очевидная проблема в том, что если одно и то же сообщение когда-нибудь шифровалось разными показателями степени (с одним и тем же модулем), и эти два показателя - взаимно простые числа (как обычно и бывает), то открытый текст может быть раскрыт, даже не зная ни одного ключа дешифрирования.

Пусть т - открытый текст сообщения. Два ключа шифрования - e1 и e2- Общий модуль - п. Шифротекстами сообщения являются:


С1= me1 mod n2 = me2 mod n


Криптоаналитик знает n,e1,e2,c1 и c2 Вот как он узнает m.

Так как e1 и e2 - взаимно простые числа, то с помощью расширенного алгоритма Эвклида r и s, для которых:


re1 + se2 = 1


Считая r отрицательным (или r, или s должно быть отрицательным, пусть отрицательным будет r), то снова можно воспользоваться расширенным алгоритмом для вычисления c1-1. Затем

(c1-1)-r *c2s = m mod n


Полученные уроки


На основании перечисленных вскрытий приводит следующие ограничения RSA:

ØЗнание одной пары показателей шифрования/дешифрирования для данного модуля позволяет взломщику разложить модуль на множители.

ØЗнание одной пары показателей шифрования/дешифрирования для данного модуля позволяет взломщику вычислить другие пары показателей, не раскладывая модуль на множители.

ØB протоколах сетей связи, применяющих RSA, не должен использоваться общий модуль. (Это является быть очевидным следствием предыдущих двух пунктов.)

ØДля предотвращения вскрытия малого показателя шифрования сообщения должны быть дополнены слyчайными значениями.

ØПоказатель дешифрирования должен быть большим.

He забывайте, недостаточно использовать безопасный криптографический алгоритм, должны быть безопаcными вся криптосистема и криптографический протокол. Слабое место любого из трех этих компонентов сделaет небезопасной всю систему-впрочем, я об этом говорил в самом начале.

Вскрытие шифрования и подписи с использованием RSA

Имеет смысл подписывать сообщение перед шифрованием но на практике никто не выполняет этого. Для RSA можно вскрыть протоколы, шифрующие сообщение до его подписания.

А хочет послать сообщение B. Сначала он шифрует его открытым ключом B, а затем подписывает своим закрытым ключом. Eго зашифрованное и подписанное сообщение выглядит так:

(meb mod nb)da mod na


Вот как B может доказать, что А послал ему m', а не т. Так как B известно разложение на множители пв (это его собственный модуль), он может вычислить дискретные логарифмы по основанию nв. Следовательно, ему нужно только найти x, для которого


mx = m mod nв


Тогда, если он может опубликовать хев в качестве своего нового открытого показателя степени и сохранить свой прежний модуль nв, он сможет утверждать, что А послал ему сообщение m', зашифрованное этим новым показателем.

B некоторых случаях это особенно неприятное вскрытие. Заметим, что хэш-функции не решают проблему. Однако она решается при использовании для каждого пользователя фиксированного показателя шифрования.


Шифр Эль Гамаля


1.Криптографы постоянно вели поиски более эффективных систем открытого шифрования, и в 1985 году Эль Гамаль предложил следующую схему на основе возведения в степень по модулю большого простого числа. Для этого задается большое простое число Р. Сообщения представляются целыми числами S из интервала (1, Р). Оригинальный протокол передачи сообщения S выглядит в варианте Шамира, одного из авторов RSA, так: 1. Отправитель А и получатель В знают лишь Р. А генерирует случайное число Х из

2.интервала (1,Р) и В тоже генерирует случайное число Y из того же интервала.

.А шифрует сообщение S1=S**X MOD Р и посылает В. 3. В шифрует его своим ключом S2=S1**Y MOD Р и посылает S2 к А. 4. А "снимает" свой ключ S3=S2**(-X) MOD Р и возвращает S3 к В. 5. Получатель В расшифровывает сообщение: S=S3**(-Y) MOD Р.

Этот протокол можно применить, например, для таких неожиданных целей, как игра в очко или блэкджек по телефону. Крупье шифрует карты своим ключом и передает их игроку. Игрок выбирает наугад одну из карт, шифрует карты своим ключом и возвращает их крупье. Крупье "снимает" с выбранной карты свой ключ и отсылает ее игроку. "Сняв" с этой карты свой ключ игрок узнает ее номинал и принимает решение: спасовать, тянуть еще или раскрываться. Теперь, хотя колода находится у крупье, но он не может ее раскрыть, так как карты зашифрованы ключом игрока. Крупье выбирает свою карту аналогично игроку. (Аналогичный алгоритм для игры в карты можно реализовать и на основе шифрования заменой операцией XOR. Однако им нельзя распространять ключи из-за легкого перехвата и взлома.)

В системе Эль Гамаля большая степень защиты, чем у алгоритма RSA достигается с тем же по размеру N, что позволяет почти на порядок увеличить скорость шифрования и расшифрования. Криптостойкость системы ЭльГамаля основана на том, что можно легко вычислить степень целого числа, то есть произвести умножение его самого на себя любое число раз так же, как и при операциях с обычными числами. Однако трудно найти показатель степени, в которую нужно возвести заданное число, чтобы получить другое, тоже заданное. В общем случае эта задача дискретного логарифмирования кажется более трудной, чем разложение больших чисел на простые сомножители, на основании чего можно предположить, что сложности вскрытия систем RSA и Эль Гамаля будут сходными. С точки зрения практической реализации, как программным, так и аппаратным способом ощутимой разницы между этими двумя стандартами нет. Однако в криптостойкости они заметно различаются. Если рассматривать задачу разложения произвольного целого числа длиной в 512 бит на простые множители и задачу логарифмирования целых чисел по 512 бит, вторая задача, по оценкам математиков, несравненно сложнее первой. Однако есть одна особенность. Если в системе, построенной с помощью алгоритма RSA, криптоаналитику удалось разложить открытый ключ N одного из абонентов на два простых числа, то возможность злоупотреблений ограничивается только этим конкретным пользователем. В случае же системы, построенной с помощью алгоритма Эль Гамаля, угрозе раскрытия подвергнутся все абоненты криптографической сети. Кроме того, упомянутые выше Ленстра и Манасси не только поколебали стойкость RSA, разложив девятое число Ферма на простые множители за неприлично короткое время, но и, как было замечено некоторыми экспертами, указали "брешь" в способе Эль Гамаля. Дело в том, что подход, применявшийся при разложении на множители девятого числа Ферма, позволяет существенно усовершенствовать методы дискретного логарифмирования для отдельных специальных простых чисел. То есть тот, кто предлагает простое Р для алгоритма Эль Гамаля, имеет возможность выбрать специальное простое, для которого задача дискретного логарифмирования будет вполне по силам обычным ЭВМ. Следует заметить, что этот недостаток алгоритма Эль Гамаля не фатален. Достаточно предусмотреть процедуру, гарантирующую случайность выбора простого Р в этой системе, и тогда только что высказанное возражение теряет силу. Стоит отметить, что чисел специального вида, ослабляющих метод Эль Гамаля, очень мало и случайным их выбором можно пренебречь.

И наконец, последняя часть - цифровые подписи


Цифровые подписи (сигнатура)


B августе 1991 года Национальный институт стандартов и техники Rational Institute of Standards and Technology, MST) предложил для использования в своем Стандарте цифровой подписи (Digital Signature Standard, DSS) Алгоритм цифровой подписи (Digital Signature Algorithm, DSA).

Описание DSA

DSA, представляющий собой вариант алгоритмов подписи EIGamal.

Алгоритм использует следующие параметры :

p = простое число длиной L битов, где L принимает значение, кратное 64, в диапазоне от 512 до 1024 (в первоначальном стандарте размер p был фиксирован и равен 512 битам ).

q = 160-битовой простое число - множитель p-1.

g = h(p-1)/q mod p, где h - любое число, меньшее p-l, для которого h(p-1)/q mod p больше 1.

x = число, меньшее q.

у = gx mod p.

B алгоритме также используется однонаправленная хэш-функция : H(m)

Первые три параметра, p, q и g, открыты и могут быть общими для пользователей сети . Закрытым ключом является x, а открытым - у. Чтобы подписать сообщение, т:

  1. А генерирует случайное число k, меньшее q
  2. А генерирует

r = (gk mod p) mod q = (k-1 (H(m) + xr)) mod q

Eго подписью служат параметры r и s, он посылает их В.

(3)В проверяет подпись, вычисляяw = s-1 mod q

u1 = (H(m} * w) mod q

u2 = (rw) mod q

v = ((g"1 *y"2 ) mod p) mod q

Если v = r, то подпись правильна.

Таблица представляет собой краткое описание алгоритма.

Подписи DSA

Открытый ключp простое число длиной от 512 до 1024 битов (может использоваться группой пользователей)q160-битовый простой множитель р-1g=h(p-1)/q mod p, где h любое число меньше p-1, для которого h(p-1)/q >1y=gx mod p -p битовое числоЗакрытый ключx < q (160-битовое число)Подпись:kвыбирается случайно, меньшее qr(подпись)=(gk mod p) mod q s(подпись)=(k-1 (H(m)+xr)) mod qПроверкаws-1mod qu1(H(m)*w)modqu2(rw) mod qV= ((gu1 *yu2) mod p) mod qЕсли v = r, то подпись правильна.

Ускоряющие предварительные вычисления

Ниже приведены примеры скорости работы программных реализаций DSA .


Скорость DSA для различных длин модулей с 160-битовым показателем степени

512битов 768битов 1024битаПодпись 0.20 с0.43 с0.57 с

Проверка 0.35c0.80c1.27c

Практические реализации DSA часто можно ускорить с помощью предварительных вычислений. Обратите внимание, что значение r не зависит от сообщения. Можно создать строку случайных значений k, и затем рассчитать значения r для каждого из них. Можно также вычислить k-1 для каждого из этих значений k. Затем, когда приходит сообщение, можно вычислить s для заданных r и k-1.

Эти предварительные вычисления заметно ускоряют DSA. Ниже приведены сравнения времени вычисления DSA и RSA для конкретной реализации интеллектуальной карточки [

Сравнение времени вычислений RSA и DSA


DSA RSA DSA с общими р, q, g Глобальные вычисления Off-card (P) N/A Off-card (P) Генерация ключа 14с Off-card (S) 4с Предварительные вычисления 14с N/A 4с Подпись 0.03с 15c 0.03с Проверка 16с 1.5с Юс 1-5 с off-card (P) 1-3 с off-card (P)

B обоих алгоритмах используется 512-битовый модуль.

Шифрование ElGamal с DSA

Утверждалось, что DSA так нравится правительству, потому что его нельзя использовать в качестве алгoритма шифрования. Однако можно использовать вызов функции DSA для шифрования EIGamal. Пусть алгоритм реализован как вызов одной функции


DSAsign (p, q, g, k, x, h, r, s)


Задав входные значения p, q, g, k, x и h, можно получить параметры подписи: r и s.

Для шифрования сообщения m алгоритмом EIGamal с помощью открытого ключа у выберем случайное число k и вызовем


DSAsign (p,p, g, k, 0, 0, r, s)


Возвращенное значение r и будет а из схемы EIGamal. Отбросим s. Затем вызовем:

DSAsign (p,p, у, k, 0, 0, r, s)


Переименуем значение r в u, отбросим s. Вызовем


DSAsign (p,p,m,l,u,O,r,s)


Отбросим r. Возвращенное значение s и будет b в схеме EIGamal. Теперь у вас есть шифротекст, а и b. Дешифрирование также просто. Используя закрытый ключ x и шифротекст сообщений, а и b, вызовем


DSAsign (p,p,a,x,0,0,r,s)


Значение r - это ax mod p. Назовем его e. Затем:

DSAsign (p,p,1,e,b,0,r,s)

Значение s и будет открытым текстом сообщения, m.

Этот способ работает не со всеми реализациями DSA - в некоторых из них могут быть зафиксированы знaчения p и q или длины некоторых других параметров. Тем не менее, если реализация является достаточно общей, то можно шифровать сообщение, не используя ничего, кроме функции цифровой подписи.


Шифрование RSA с DSA


Шифрование RSA еще проще. Используя модуль n, сообщение т и открытый ключ e, вызовем

DSAsign (n,n,m,e,0,0,r,s)

Возвращенное значение r и есть шифротекст. Дешифрирование RSA является точно таким же. Если d - закрытый ключ, то

DSAsign (n,n,m,d,0,0,r,s)

возвращает открытый текст как значение r.

Заключение


В данной работе я дал краткий обзор основных систем криптографии. Следует уточнить- я описывал классические, традиционные, системы шифрования. Конечно существуют и другие реализации симметричных систем (LOKI, NewDES, IDEA, SKIPJAK и.т.д) и систем с открытым ключём (LUC, Rabin)- но принцип действия, у них остается таким-же. Иными словами, я не задавался целью описать все известные системы- целью являлось дать общее описание, и по возможности простым языком.

В конце работы хочу привести исодные коды некоторых алгоритмов (на С)

Недавно меня спросили «А почему С?. Почему, скажем не Delphi, VisualBasic?»

Ответ на данной вопрос довольно прост…. Ну хотябы начнём с того что большинство современных языков базируются на С… точнее будет сказать что концепция обектно-орентированного программирования впервые была применнена в С++.Второе это то что любое написанное на С приложение достаточно легко перенести на другую платформу, например под UNIX. Ну и третьё и заключительное утверждение- Все алгоритмы киптографических систем публикуются и доступны всему миру на С++! Пожалуй этих трех аргументов достаточно, чтоб оправдять и сам выбор языка и меня .

Список литературы


1)Bruce Schneier, "Applied Cryptography: Protocols, Algorithms, and Source Code in C"

2)Landreth, Bill, A Hacker's Guide to Computer Security

3)Friedman, W.F., -Elements of Cryptanalysis

)Sarnoff, Jane and Ruffins, Reynold.- The Code and Cipher Book

5)Владимир Жельников Криптография от папируса до компьютер

6)<#"justify">Приложение


DES


// The following DES code has been based and modified from "ALLENDES"

// by Steve Allen. 32 bit modifications, and MS visual C++ wrappers and

// implementations by Aman for inclusion into the "Scramdisk" system for

// MS Windows standard, and 3 key triple des, implemented. CBC feedback

// implemented by the caller. (outer CBC)



#define DES_ENCRYPT 1

#define DES_DECRYPT 0





//#define DEVICEDRIVER // uncomment for driver code......

struct deskey// scramdisk key storage (in ram)

{char e[16*8];char d[16*8]; // key 2only used in EDE 3des mode......char e2[16*8];// key 3 only used in EDE 3des mode

}deskey;




#ifdef DEVICEDRIVER

#pragma VxD_LOCKED_DATA_SEG

#endif

sdisk_des_keys[8];// 4 scramdisk disks






#if DEVICEDRIVER


#pragma VxD_LOCKED_DATA_SEG


#endif


long p1[]=

{

0x00000000, 0x00000000,

0x01000000, 0x00000000,

x00000000, 0x01000000,

x01000000, 0x01000000,

x00010000, 0x00000000,

x01010000, 0x00000000,

x00010000, 0x01000000,

x01010000, 0x01000000,

x00000000, 0x00010000,

x01000000, 0x00010000,

x00000000, 0x01010000,

x01000000, 0x01010000,

x00010000, 0x00010000,

x01010000, 0x00010000,

x00010000, 0x01010000,

x01010000, 0x01010000,

x00000000, 0x00000000,

x00000100, 0x00000000,

x00000000, 0x00000100,

x00000100, 0x00000100,

x00000001, 0x00000000,

x00000101, 0x00000000,

x00000001, 0x00000100,

x00000101, 0x00000100,

x00000000, 0x00000001,

x00000100, 0x00000001,

x00000000, 0x00000101,

x00000100, 0x00000101,

x00000001, 0x00000001,

x00000101, 0x00000001,

x00000001, 0x00000101,

x00000101, 0x00000101,


x00000000, 0x00000000,

x02000000, 0x00000000,

x00000000, 0x02000000,

x02000000, 0x02000000,

x00020000, 0x00000000,

x02020000, 0x00000000,

x00020000, 0x02000000,

x02020000, 0x02000000,

x00000000, 0x00020000,

x02000000, 0x00020000,

x00000000, 0x02020000,

x02000000, 0x02020000,

x00020000, 0x00020000,

x02020000, 0x00020000,

x00020000, 0x02020000,

x02020000, 0x02020000,

x00000000, 0x00000000,

x00000200, 0x00000000,

x00000000, 0x00000200,

x00000200, 0x00000200,

x00000002, 0x00000000,

x00000202, 0x00000000,

x00000002, 0x00000200,

x00000202, 0x00000200,

x00000000, 0x00000002,

x00000200, 0x00000002,

x00000000, 0x00000202,

x00000200, 0x00000202,

x00000002, 0x00000002,

x00000202, 0x00000002,

x00000002, 0x00000202,

x00000202, 0x00000202,


x00000000, 0x00000000,

x04000000, 0x00000000,

x00000000, 0x04000000,

x04000000, 0x04000000,

x00040000, 0x00000000,

x04040000, 0x00000000,

x00040000, 0x04000000,

x04040000, 0x04000000,

x00000000, 0x00040000,

x04000000, 0x00040000,

x00000000, 0x04040000,

x04000000, 0x04040000,

x00040000, 0x00040000,

x04040000, 0x00040000,

x00040000, 0x04040000,

x04040000, 0x04040000,

x00000000, 0x00000000,

x00000400, 0x00000000,

x00000000, 0x00000400,

x00000400, 0x00000400,

x00000004, 0x00000000,

x00000404, 0x00000000,

x00000004, 0x00000400,

x00000404, 0x00000400,

x00000000, 0x00000004,

x00000400, 0x00000004,

x00000000, 0x00000404,

x00000400, 0x00000404,

x00000004, 0x00000004,

x00000404, 0x00000004,

x00000004, 0x00000404,

x00000404, 0x00000404,


x00000000, 0x00000000,

x08000000, 0x00000000,

x00000000, 0x08000000,

x08000000, 0x08000000,

x00080000, 0x00000000,

x08080000, 0x00000000,

x00080000, 0x08000000,

x08080000, 0x08000000,

x00000000, 0x00080000,

x08000000, 0x00080000,

x00000000, 0x08080000,

x08000000, 0x08080000,

x00080000, 0x00080000,

x08080000, 0x00080000,

x00080000, 0x08080000,

x08080000, 0x08080000,

x00000000, 0x00000000,

x00000800, 0x00000000,

x00000000, 0x00000800,

x00000800, 0x00000800,

x00000008, 0x00000000,

x00000808, 0x00000000,

x00000008, 0x00000800,

x00000808, 0x00000800,

x00000000, 0x00000008,

x00000800, 0x00000008,

x00000000, 0x00000808,

x00000800, 0x00000808,

x00000008, 0x00000008,

x00000808, 0x00000008,

x00000008, 0x00000808,

x00000808, 0x00000808,


x00000000, 0x00000000,

x10000000, 0x00000000,

x00000000, 0x10000000,

x10000000, 0x10000000,

x00100000, 0x00000000,

x10100000, 0x00000000,

x00100000, 0x10000000,

x10100000, 0x10000000,

x00000000, 0x00100000,

x10000000, 0x00100000,

x00000000, 0x10100000,

x10000000, 0x10100000,

x00100000, 0x00100000,

x10100000, 0x00100000,

x00100000, 0x10100000,

x10100000, 0x10100000,

x00000000, 0x00000000,

x00001000, 0x00000000,

x00000000, 0x00001000,

x00001000, 0x00001000,

x00000010, 0x00000000,

x00001010, 0x00000000,

x00000010, 0x00001000,

x00001010, 0x00001000,

x00000000, 0x00000010,

x00001000, 0x00000010,

x00000000, 0x00001010,

x00001000, 0x00001010,

x00000010, 0x00000010,

x00001010, 0x00000010,

x00000010, 0x00001010,

x00001010, 0x00001010,


x00000000, 0x00000000,

x20000000, 0x00000000,

x00000000, 0x20000000,

x20000000, 0x20000000,

x00200000, 0x00000000,

x20200000, 0x00000000,

x00200000, 0x20000000,

x20200000, 0x20000000,

x00000000, 0x00200000,

x20000000, 0x00200000,

x00000000, 0x20200000,

x20000000, 0x20200000,

x00200000, 0x00200000,

x20200000, 0x00200000,

x00200000, 0x20200000,

x20200000, 0x20200000,

x00000000, 0x00000000,

x00002000, 0x00000000,

x00000000, 0x00002000,

x00002000, 0x00002000,

x00000020, 0x00000000,

x00002020, 0x00000000,

x00000020, 0x00002000,

x00002020, 0x00002000,

x00000000, 0x00000020,

x00002000, 0x00000020,

x00000000, 0x00002020,

x00002000, 0x00002020,

x00000020, 0x00000020,

x00002020, 0x00000020,

x00000020, 0x00002020,

x00002020, 0x00002020,


x00000000, 0x00000000,

x40000000, 0x00000000,

x00000000, 0x40000000,

x40000000, 0x40000000,

x00400000, 0x00000000,

x40400000, 0x00000000,

x00400000, 0x40000000,

x40400000, 0x40000000,

x00000000, 0x00400000,

x40000000, 0x00400000,

x00000000, 0x40400000,

x40000000, 0x40400000,

x00400000, 0x00400000,

x40400000, 0x00400000,

x00400000, 0x40400000,

x40400000, 0x40400000,

x00000000, 0x00000000,

x00004000, 0x00000000,

x00000000, 0x00004000,

x00004000, 0x00004000,

x00000040, 0x00000000,

x00004040, 0x00000000,

x00000040, 0x00004000,

x00004040, 0x00004000,

x00000000, 0x00000040,

x00004000, 0x00000040,

x00000000, 0x00004040,

x00004000, 0x00004040,

x00000040, 0x00000040,

x00004040, 0x00000040,

x00000040, 0x00004040,

x00004040, 0x00004040,


x00000000, 0x00000000,

x80000000, 0x00000000,

x00000000, 0x80000000,

x80000000, 0x80000000,

x00800000, 0x00000000,

x80800000, 0x00000000,

x00800000, 0x80000000,

x80800000, 0x80000000,

x00000000, 0x00800000,

x80000000, 0x00800000,

x00000000, 0x80800000,

x80000000, 0x80800000,

x00800000, 0x00800000,

x80800000, 0x00800000,

x00800000, 0x80800000,

x80800000, 0x80800000,

x00000000, 0x00000000,

x00008000, 0x00000000,

x00000000, 0x00008000,

x00008000, 0x00008000,

x00000080, 0x00000000,

x00008080, 0x00000000,

x00000080, 0x00008000,

x00008080, 0x00008000,

x00000000, 0x00000080,

x00008000, 0x00000080,

x00000000, 0x00008080,

x00008000, 0x00008080,

x00000080, 0x00000080,

x00008080, 0x00000080,

x00000080, 0x00008080,

x00008080, 0x00008080


};

long p2[]=

{

x00000000, 0x00000000,

x00000040, 0x00000000,

x00004000, 0x00000000,

x00004040, 0x00000000,

x00400000, 0x00000000,

x00400040, 0x00000000,

x00404000, 0x00000000,

x00404040, 0x00000000,

x40000000, 0x00000000,

x40000040, 0x00000000,

x40004000, 0x00000000,

x40004040, 0x00000000,

x40400000, 0x00000000,

x40400040, 0x00000000,

x40404000, 0x00000000,

x40404040, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000040,

x00000000, 0x00004000,

x00000000, 0x00004040,

x00000000, 0x00400000,

x00000000, 0x00400040,

x00000000, 0x00404000,

x00000000, 0x00404040,

x00000000, 0x40000000,

x00000000, 0x40000040,

x00000000, 0x40004000,

x00000000, 0x40004040,

x00000000, 0x40400000,

x00000000, 0x40400040,

x00000000, 0x40404000,

x00000000, 0x40404040,


x00000000, 0x00000000,

x00000010, 0x00000000,

x00001000, 0x00000000,

x00001010, 0x00000000,

x00100000, 0x00000000,

x00100010, 0x00000000,

x00101000, 0x00000000,

x00101010, 0x00000000,

x10000000, 0x00000000,

x10000010, 0x00000000,

x10001000, 0x00000000,

x10001010, 0x00000000,

x10100000, 0x00000000,

x10100010, 0x00000000,

x10101000, 0x00000000,

x10101010, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000010,

x00000000, 0x00001000,

x00000000, 0x00001010,

x00000000, 0x00100000,

x00000000, 0x00100010,

x00000000, 0x00101000,

x00000000, 0x00101010,

x00000000, 0x10000000,

x00000000, 0x10000010,

x00000000, 0x10001000,

x00000000, 0x10001010,

x00000000, 0x10100000,

x00000000, 0x10100010,

x00000000, 0x10101000,

x00000000, 0x10101010,


x00000000, 0x00000000,

x00000004, 0x00000000,

x00000400, 0x00000000,

x00000404, 0x00000000,

x00040000, 0x00000000,

x00040004, 0x00000000,

x00040400, 0x00000000,

x00040404, 0x00000000,

x04000000, 0x00000000,

x04000004, 0x00000000,

x04000400, 0x00000000,

x04000404, 0x00000000,

x04040000, 0x00000000,

x04040004, 0x00000000,

x04040400, 0x00000000,

x04040404, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000004,

x00000000, 0x00000400,

x00000000, 0x00000404,

x00000000, 0x00040000,

x00000000, 0x00040004,

x00000000, 0x00040400,

x00000000, 0x00040404,

x00000000, 0x04000000,

x00000000, 0x04000004,

x00000000, 0x04000400,

x00000000, 0x04000404,

x00000000, 0x04040000,

x00000000, 0x04040004,

x00000000, 0x04040400,

x00000000, 0x04040404,


x00000000, 0x00000000,

x00000001, 0x00000000,

x00000100, 0x00000000,

x00000101, 0x00000000,

x00010000, 0x00000000,

x00010001, 0x00000000,

x00010100, 0x00000000,

x00010101, 0x00000000,

x01000000, 0x00000000,

x01000001, 0x00000000,

x01000100, 0x00000000,

x01000101, 0x00000000,

x01010000, 0x00000000,

x01010001, 0x00000000,

x01010100, 0x00000000,

x01010101, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000001,

x00000000, 0x00000100,

x00000000, 0x00000101,

x00000000, 0x00010000,

x00000000, 0x00010001,

x00000000, 0x00010100,

x00000000, 0x00010101,

x00000000, 0x01000000,

x00000000, 0x01000001,

x00000000, 0x01000100,

x00000000, 0x01000101,

x00000000, 0x01010000,

x00000000, 0x01010001,

x00000000, 0x01010100,

x00000000, 0x01010101,


x00000000, 0x00000000,

x00000080, 0x00000000,

x00008000, 0x00000000,

x00008080, 0x00000000,

x00800000, 0x00000000,

x00800080, 0x00000000,

x00808000, 0x00000000,

x00808080, 0x00000000,

x80000000, 0x00000000,

x80000080, 0x00000000,

x80008000, 0x00000000,

x80008080, 0x00000000,

x80800000, 0x00000000,

x80800080, 0x00000000,

x80808000, 0x00000000,

x80808080, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000080,

x00000000, 0x00008000,

x00000000, 0x00008080,

x00000000, 0x00800000,

x00000000, 0x00800080,

x00000000, 0x00808000,

x00000000, 0x00808080,

x00000000, 0x80000000,

x00000000, 0x80000080,

x00000000, 0x80008000,

x00000000, 0x80008080,

x00000000, 0x80800000,

x00000000, 0x80800080,

x00000000, 0x80808000,

x00000000, 0x80808080,


x00000000, 0x00000000,

x00000020, 0x00000000,

x00002000, 0x00000000,

x00002020, 0x00000000,

x00200000, 0x00000000,

x00200020, 0x00000000,

x00202000, 0x00000000,

x00202020, 0x00000000,

x20000000, 0x00000000,

x20000020, 0x00000000,

x20002000, 0x00000000,

x20002020, 0x00000000,

x20200000, 0x00000000,

x20200020, 0x00000000,

x20202000, 0x00000000,

x20202020, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000020,

x00000000, 0x00002000,

x00000000, 0x00002020,

x00000000, 0x00200000,

x00000000, 0x00200020,

x00000000, 0x00202000,

x00000000, 0x00202020,

x00000000, 0x20000000,

x00000000, 0x20000020,

x00000000, 0x20002000,

x00000000, 0x20002020,

x00000000, 0x20200000,

x00000000, 0x20200020,

x00000000, 0x20202000,

x00000000, 0x20202020,


x00000000, 0x00000000,

x00000008, 0x00000000,

x00000800, 0x00000000,

x00000808, 0x00000000,

x00080000, 0x00000000,

x00080008, 0x00000000,

x00080800, 0x00000000,

x00080808, 0x00000000,

x08000000, 0x00000000,

x08000008, 0x00000000,

x08000800, 0x00000000,

x08000808, 0x00000000,

x08080000, 0x00000000,

x08080008, 0x00000000,

x08080800, 0x00000000,

x08080808, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000008,

x00000000, 0x00000800,

x00000000, 0x00000808,

x00000000, 0x00080000,

x00000000, 0x00080008,

x00000000, 0x00080800,

x00000000, 0x00080808,

x00000000, 0x08000000,

x00000000, 0x08000008,

x00000000, 0x08000800,

x00000000, 0x08000808,

x00000000, 0x08080000,

x00000000, 0x08080008,

x00000000, 0x08080800,

x00000000, 0x08080808,


x00000000, 0x00000000,

x00000002, 0x00000000,

x00000200, 0x00000000,

x00000202, 0x00000000,

x00020000, 0x00000000,

x00020002, 0x00000000,

x00020200, 0x00000000,

x00020202, 0x00000000,

x02000000, 0x00000000,

x02000002, 0x00000000,

x02000200, 0x00000000,

x02000202, 0x00000000,

x02020000, 0x00000000,

x02020002, 0x00000000,

x02020200, 0x00000000,

x02020202, 0x00000000,

x00000000, 0x00000000,

x00000000, 0x00000002,

x00000000, 0x00000200,

x00000000, 0x00000202,

x00000000, 0x00020000,

x00000000, 0x00020002,

x00000000, 0x00020200,

x00000000, 0x00020202,

x00000000, 0x02000000,

x00000000, 0x02000002,

x00000000, 0x02000200,

x00000000, 0x02000202,

x00000000, 0x02020000,

x00000000, 0x02020002,

x00000000, 0x02020200,

x00000000, 0x02020202



};



char Pmask[]=

{

x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01

};



char PC1tbl[]=

{

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};

char PC2tbl[]=

{

x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,

x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,

x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,

x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,

x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,

x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,

x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,

x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,

x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,

x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00

};

long sp_table[]= // label dword

{

// sp[0]

x00828000,

x00000000,

x00800000,

x02828000,

x02808000,

x02820000,

x02000000,

x00800000,

x00020000,

x00828000,

x02828000,

x00020000,

x02028000,

x02808000,

x00008000,

x02000000,

x02020000,

x00028000,

x00028000,

x00820000,

x00820000,

x00808000,

x00808000,

x02028000,

x02800000,

x02008000,

x02008000,

x02800000,

x00000000,

x02020000,

x02820000,

x00008000,

x00800000,

x02828000,

x02000000,

x00808000,

x00828000,

x00008000,

x00008000,

x00020000,

x02808000,

x00800000,

x00820000,

x02008000,

x00020000,

x02000000,

x02028000,

x02820000,

x02828000,

x02800000,

x00808000,

x02028000,

x02008000,

x02020000,

x02820000,

x00828000,

x02020000,

x00028000,

x00028000,

x00000000,

x02800000,

x00820000,

x00000000,

x02808000,

//; sp[1]

x10400840,

x00400040,

x00400000,

x10400800,

x00000800,

x10000000,

x10000840,

x10400040,

x10000040,

x10400840,

x00400840,

x00000040,

x00400040,

x00000800,

x10000000,

x10000840,

x00400800,

x10000800,

x10400040,

x00000000,

x00000040,

x00400000,

x10400800,

x00000840,

x10000800,

x10000040,

x00000000,

x00400800,

x10400000,

x00400840,

x00000840,

x10400000,

x00000000,

x10400800,

x10000840,

x00000800,

x10400040,

x00000840,

x00400840,

x00400000,

x00000840,

x00400040,

x10000000,

x10400840,

x10400800,

x10000000,

x00400000,

x00000040,

x10400000,

x00400840,

x00000800,

x10000040,

x10000800,

x10400040,

x10000040,

x10000800,

x00400800,

x00000000,

x00400040,

x10400000,

x00000040,

x10000840,

x10400840,

x00400800,

//; sp[2]

x04010000,

x00010104,

x00000000,

x04000104,

x00010004,

x00000000,

x04010100,

x00010004,

x04000100,

x04000004,

x04000004,

x00000100,

x04010104,

x04000100,

x00000104,

x04010000,

x00000004,

x04000000,

x00010104,

x00010000,

x00010100,

x00000104,

x04000104,

x04010100,

x04010004,

x00010100,

x00000100,

x04010004,

x04000000,

x04010104,

x00010000,

x00000004,

x00010104,

x00000004,

x04000100,

x04010000,

x00000100,

x00010104,

x00010004,

x00000000,

x00010000,

x04000100,

x04010104,

x00010004,

x04000004,

x00010000,

x00000000,

x04000104,

x04010004,

x00000100,

x00000004,

x04010104,

x04000000,

x04010100,

x00010100,

x04000004,

x00000104,

x04010004,

x04010000,

x00000104,

x04010100,

x04000000,

x04000104,

x00010100,

//; sp[3]

x00104080,

x40100080,

x40100080,

x40000000,

x40104000,

x40004080,

x00004080,

x00100080,

x00000000,

x00104000,

x00104000,

x40104080,

x40000080,

x00000000,

x40004000,

x00004080,

x00000080,

x00100000,

x00004000,

x00104080,

x40000000,

x00004000,

x00100080,

x40100000,

x40004080,

x00000080,

x40100000,

x40004000,

x00100000,

x40104000,

x40104080,

x40000080,

x40004000,

x00004080,

x00104000,

x40104080,

x40000080,

x00000000,

x00000000,

x00104000,

x40100000,

x40004000,

x40004080,

x00000080,

x00104080,

x40100080,

x40100080,

x40000000,

x40104080,

x40000080,

x00000080,

x00100000,

x00004080,

x00100080,

x40104000,

x40004080,

x00100080,

x40100000,

x00004000,

x00104080,

x40000000,

x00004000,

x00100000,

x40104000,

//; sp[4]

x80000000,

x80000401,

x00000401,

x80000021,

x00000400,

x80000000,

x00000020,

x00000401,

x80000420,

x00000400,

x80000001,

x80000420,

x80000021,

x00000421,

x80000400,

x00000020,

x00000001,

x00000420,

x00000420,

x00000000,

x80000020,

x80000421,

x80000421,

x80000001,

x00000421,

x80000020,

x00000000,

x00000021,

x80000401,

x00000001,

x00000021,

x80000400,

x00000400,

x80000021,

x80000000,

x00000001,

x00000020,

x00000401,

x80000021,

x80000420,

x80000001,

x00000020,

x00000421,

x80000401,

x80000420,

x80000000,

x00000001,

x00000421,

x80000421,

x80000400,

x00000021,

x80000421,

x00000401,

x00000000,

x00000420,

x00000021,

x80000400,

x80000001,

x80000020,

x00000400,

x00000000,

x00000420,

x80000401,

x80000020,

//; sp[5]

x08000010,

x00002010,

x00200000,

x08202010,

x00002010,

x08000000,

x08202010,

x00002000,

x00200010,

x08202000,

x00002000,

x08000010,

x08002000,

x00200010,

x00000010,

x08200000,

x00000000,

x08002000,

x08200010,

x00200000,

x00202000,

x08200010,

x08000000,

x08002010,

x08002010,

x00000000,

x08202000,

x00202010,

x08200000,

x00202000,

x00202010,

x00000010,

x00200010,

x08000000,

x08002010,

x00202000,

x08202010,

x00002000,

x08200000,

x08000010,

x00002000,

x00200010,

x00000010,

x08200000,

x08000010,

x08202010,

x00202000,

x00002010,

x08202000,

x00202010,

x00000000,

x08002010,

x08000000,

x00200000,

x00002010,

x08202000,

x00200000,

x08002000,

x08200010,

x00000000,

x00202010,

x00000010,

x08002000,

x08200010,

//; sp[6]

x00001000,

x01001002,

x01040002,

x00000000,

x00040000,

x01040002,

x01041000,

x00041002,

x01041002,

x00001000,

x00000000,

x01000002,

x01000000,

x00000002,

x01001002,

x01040000,

x00040002,

x01041000,

x01001000,

x00040002,

x01000002,

x00001002,

x00041002,

x01001000,

x00001002,

x00040000,

x01040000,

x01041002,

x00041000,

x01000000,

x00000002,

x00041000,

x00000002,

x00041000,

x00001000,

x01040002,

x01040002,

x01001002,

x01001002,

x01000000,

x01001000,

x00000002,

x00040002,

x00001000,

x00041002,

x01040000,

x01041000,

x00041002,

x01040000,

x01000002,

x01041002,

x00001002,

x00041000,

x00000000,

x01000000,

x01041002,

x00000000,

x01041000,

x00001002,

x00040000,

x01000002,

x00040002,

x00040000,

x01001000,

//; sp[7]

x20080008,

x00080000,

x00000200,

x20080208,

x00000008,

x20080008,

x20000000,

x00000008,

x20000200,

x00000208,

x20080208,

x00080200,

x00080208,

x20080200,

x00080000,

x20000000,

x00000208,

x20000008,

x00080008,

x20080000,

x00080200,

x20000200,

x20000208,

x00080208,

x20080000,

x00000000,

x00000000,

x20000208,

x20000008,

x00080008,

x20080200,

x00000200,

x20080200,

x00000200,

x00080208,

x00080000,

x20000000,

x20000208,

x00080000,

x20080200,

x00080008,

x20000000,

x20000008,

x00000208,

x20000208,

x00000008,

x00000200,

x20080008,

x00000000,

x20080208,

x20000200,

x20000008,

x00000208,

x00080008,

x20080008,

x00000000,

x20080208,

x00080200,

x00080200,

x20080000,

x20080000,

x20000200,

x00000008,

x00080208


};




//unsigned char en_keytbl[16*8];


//int loopcount;

//unsigned int block[2];


des_encrypt(unsigned int *bl,unsigned char* kp,unsigned int mode)


{


static unsigned char * keyptr;

static unsigned int loopcount;

static unsigned int block[2];


keyptr=kp;

block[0]=bl[0];

block[1]=bl[1];


_asm

{



cmp [mode],0

jz decrypt_block

;--------------------------------------------------------------------

; Local PERMUTE for encrypt_block & decrypt_block

;input conditions:

; esi:perm. table ptr

; edx:eax input high and low

; ebp:edi output high and low

; destroys all registers except cx!




;----------------------------------------------------------------------

; void encrypt_block(void);

; encrypts data in (unsigned char block[8] ),

; returning it in the same block[].


;;encrypt_block:esiediebp

esi, offset p1edx,dword ptr[block]eax,dword ptr[block+4]l_permute ;returns with output in ebp:edi

eax,edi ;f() input is ebp:eax

esi,[keyptr]

esi,7[loopcount],16 ;yes, this is the full 16 round DES

:

and ebx,0ffffh edx,eax ;prepare to operate on right halfecx,eax ;and save it: it becomes left halfedx ;edx has f() inputeax,eax ;output gets zeroedi,offset sp_table+7*4*64 ;point to combined s & p boxesedx,3 ;prepare for E() function


;THE F() FUNCTION (encrypt)bx,dx ;nybble 1bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 2bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 3bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 4bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 5bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 6bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 7bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ; (E function)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 8bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybble

eax,ebp ;left half^= f(right half,keytbl[n]);esi,16 ;point to next keytableebp,ecx ;old right half becomes new left half[loopcount]dxlp1

esi, offset p2edx,eaxeax,ebpl_permute


mov ebx,ebp


//mov dword ptr[block],ebpebp

mov [block],ebx

mov dword ptr[block+4],edi


;;pop ebpediesiddone



;----------------------------------------------------------------------_block:esiediebp

esi, offset p1edx,dword ptr[block] ;get input for l_permuteeax,dword ptr[block+4]l_permute

[loopcount],16 ;yes, this is the full 16 round DES

//ifdef TRIPLE_DES

// mov esi,[de_keyptr]

//elseesi,[keyptr]

//endifesi,15*8+7eax, edi ;ip.L=op.R


//align 4:and ebx,0ffffhedx,eax ;f() input is ip.Lecx,edx ;op.R=ip.Ledxeax,eax ;output gets zeroedi,offset sp_table + 7*4*64 ;point to s&p boxesedx,3 ;set up bits 32,1,2,3,4,5 shl 2


;THE F() FUNCTION (decrypt)bx,dx ;nybble 1bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 2bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 3bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 4bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 5bl,[esi] ;XOR with key bitsbx,11111100bsieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 6bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)edi,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 7bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybbleedx,4 ;(see E Bit-Selection Table)di,4*64 ;sizeof(long)*sizeof(table)

bx,dx ;nybble 8bl,[esi] ;XOR with key bitsbx,11111100besieax, [ebx+edi] ;set bits for this nybble

eax,ebp ;ip.R ^ f(ip.L,keytbl[n]);ebp,ecx ;ip.R=op.R;[loopcount]dxlp2

esi,offset p2 ;set up for inverse permutationedx,eax ;get inputeax,ebpl_permute

;;mov dword ptr[block],ebp

;;mov dword ptr[block+4],edi


mov ebx,ebpebp

mov [block],ebx

mov [block+4],edi

ediesiddone

_permute:


; do high dword


movzx ebx,dx ;nybble 1bx,3bx,1111000bedx,1ebp,[esi+ebx] ;output highedi,[esi+4+ebx] ;output lowesi,8*16


;@@2:bx,dx ;nybble 2bx,1111000bedx,4ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx,dx ;nybble 3bx,1111000bedx,4ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx,dx ;nybble 4bx,1111000bedx,4ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx,dx ;nybble 5bx,1111000bedx,4ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx,dx ;nybble 6bx,1111000bedx,4ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx,dx ;nybble 7bx,1111000bedx,4ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx,dx ;nybble 8bx,1111000bebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16


; do low dwordbx,ax ;nybble 1bx,3 ;index * 8bx,1111000beax,1ebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16


;@@3:bx, ax ;nybble 2bx,1111000beax,4 ;next nybbleebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx, ax ;nybble 3bx,1111000beax,4 ;next nybbleebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx, ax ;nybble 4bx,1111000beax,4 ;next nybbleebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx, ax ;nybble 5bx,1111000beax,4 ;next nybbleebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx, ax ;nybble 6bx,1111000beax,4 ;next nybbleebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx, ax ;nybble 7bx,1111000beax,4 ;next nybbleebp,[esi+ebx]edi,[esi+4+ebx]esi,8*16

bx, ax ;nybble 8bx,1111000bebp,[esi+ebx]edi,[esi+4+ebx]


:



}


bl[0]=block[0];

bl[1]=block[1];


}





permute(long *op,long *ip, char *tbl,int n)

{


_asm

{

;permute proc near

; arg op:dataptr, ip:dataptr, tbl:dataptr, n:word


; push bp

; mov bp,sp

; push si

; push di

ebx,[op]esi,[tbl] ;permutation table to siedi,offset Pmask ;setting-bits in didword ptr[ebx],0dword ptr[ebx+4],0 ;output=0ebx,[ip]eax,[ebx]edx,[ebx+4] ;input to edx:eaxecx,[n] ;count to cx

: mov ebx,[esi] ;get high dword perm biteax,ebx ;is this bit set?pmis_hitebx,[esi+4] ;get low dword perm bitedx,ebx ;any action?pmno_hit

_hit:esiesi,[op] ;point to outputebx,[edi] ;get setting-bit[esi],ebx ;set the bitebx,[edi+4] ;do for both halves[esi+4],ebx ;set bitesi

_hit:esi,8 ;next permutation entryedi,8 ;next setting-bits entrypm1



; pop di

; pop si

; mov sp,bp

; pop bp



}


}





//;----------------------------------------------------------------------

//; Rotate 28 bits (for KS function)

//; void rotate(long *input,int count);


rotate(long *input,int count)

//rotate proc near

// arg input:dataptr,count:word


{


_asm

{




mov ecx,[count]

mov ebx, [input]

mov eax,[ebx]

bswap eax ;get bits in good order

xor ebx,ebx

shld ebx, eax,cl ;shift high bits to bl

shl eax,cl

shl ebx,4 ;move from bit 32 to bit 28

add eax,ebx


mov ebx,[input]

bswap eax ;reverse bytes...

mov [ebx],eax ;...so they store correctly




}


}




set_table(char*input,int num,long*tbl)

{



_asm

{

;----------------------------------------------------------------------

; void set_table(char*input,int n,long*keytbl);

; Take a 48-bit input, and make 8 bytes of 6 bits each.

; Output goes into tbl[].

;align 16

;proc set_table near

; arg input:dataptr,num:word, tbl:dataptr


;push bp

;mov bp,sp

;push di

edi, [tbl]eax,[num]bl,8bledi,eax ;now di points to proper offset in keytblebx,[input]dx,word ptr[ebx+4]edx ;edx highbits now has highbits of key sched.ebx,[ebx]ebx ;ebx gets 48 bits of key sched.cx,8 ;loop count

: shld eax,ebx,6 ;get next 6 bitsebx,edx,6edx,6ax,2 ;pre-shift for sizeof(long) in f() functional,11111100b[edi],aledistble1


;pop di

;mov sp,bp

;pop bp


}


}




des_key_sched(char * password, unsigned char *keytble)

{


static char *input;

static unsigned char *tbl;

static unsigned long block1[2];

static unsigned long temp [2];



static loopcount;


static unsigned short r_sched[]=

{

1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1


};

input=password;

tbl=keytble;


_asm

{




;----------------------------------------------------------------------

; void schedule(char *password long keytbl[]);

; Expand a password into 16 rounds of Key Schedule.

; Output goes into extern keytbl[16][8]

; (This is not a time-critical function, and I simply

; rewrote the c source into assembler, to make

; DES programming a 2-step process-- schedule the key,

; encrypt/decrypt the block.)

;align 16

;proc schedule

; arg input:dataptr, tbl:dataptr


ebp

;mov bp,spedi

64offset PC1tblebx,[input]ebxoffset temppermute ;select 56 bitssp,8*2

ecx,16[loopcount],ecxedi,edi

:ebx,ediebx,1ebx,offset r_schedeax,[word ptr ebx]eax ;save for 2nd rotate



push eax ;arg for rotate func.offset temprotateesp,4*2

offset temp+4rotateesp,4*2

48offset PC2tbl ;perm tableoffset temp ;inputoffset block1 ;outputpermuteesp,8*2

eax,[tbl]eaxedi ;table numberoffset block1 ;inputset_tableesp,6*2

edi[loopcount]sch1

ebx,[input] ;erase the password spacecx,4ax,ax: mov [ebx],axebxebxsch2

ediebpscdone




;;set_table:




:

}


}








// Scramdisk specific code.....


//key schedules

// Three key triple des...




desencipher(unsigned long *b, int slot)

{

des_encrypt(b,sdisk_des_keys[slot].e,DES_ENCRYPT);

}

threedesencipher(unsigned long *b, int slot)

{

des_encrypt(b, sdisk_des_keys[slot].e,DES_ENCRYPT);

des_encrypt(b, sdisk_des_keys[slot].d,DES_DECRYPT);

des_encrypt(b, sdisk_des_keys[slot].e2,DES_ENCRYPT);

}



desdecipher(unsigned long *b, int slot)

{

des_encrypt(b, sdisk_des_keys[slot].e,DES_DECRYPT);

}

threedesdecipher(unsigned long *b, int slot)

{

des_encrypt(b, sdisk_des_keys[slot].e2,DES_DECRYPT);

des_encrypt(b, sdisk_des_keys[slot].d,DES_ENCRYPT);

des_encrypt(b, sdisk_des_keys[slot].e,DES_DECRYPT);

}


desinitialise(char *key,int slot)

{_key_sched(key,sdisk_des_keys[slot].e);

}



threedesinitialise(char *key,int slot)

{*key2=key+8;*key3=key2+8;_key_sched(key,sdisk_des_keys[slot].e);_key_sched(key2,sdisk_des_keys[slot].d);_key_sched(key3,sdisk_des_keys[slot].e2);

}




//;1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A

main (void) //test code

{


//char keytable[16*8];char key[]=

{

0x1f,0x08,0x26,0x0d,0x1a,0xc2,0x46,0x5e

};


char key3[]=

{

0x1f,0x08,0x26,0x0d,0x1a,0xc2,0x46,0x5e,

0x44,0x28,0x1d,0x6b,0x61,0x11,0x52,0x47,

0x12,0x41,0x34,0x26,0x1d,0x3e,0xf4,0x45

};


char cipher[]=

{

0xef,0x1b,0xf0,0x3e,0x5d,0xfa,0x57,0x5a //cipher text...

};

//void Eblock(unsigned int mode,unsigned int *kp,unsigned int *bl)


//des_key_sched((unsigned char *) &key,keytable);

//des_encrypt((unsigned int *) cipher,keytable,0);

//des_encrypt((unsigned int *) cipher,keytable,1);



desinitialise(key,0);

desdecipher((unsigned long *) cipher,0);

desencipher((unsigned long *) cipher,0);



threedesinitialise(key3,0);

threedesdecipher((unsigned long *) cipher,0);

threedesencipher((unsigned long *) cipher,0);


cout<< Enter key;



}





GOST

/*

* The GOST 28147-89 cipher

*

* This is based on the 25 Movember 1993 draft translation

* by Aleksandr Malchik, with Whitfield Diffie, of the Government

* Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation

* Algorithm", effective 1 July 1990. ([email protected])

*

* That is a draft, and may contain errors, which will be faithfully

* reflected here, along with possible exciting new bugs.

*

* Some details have been cleared up by the paper "Soviet Encryption

* Algorithm" by Josef Pieprzyk and Leonid Tombak of the University

* of Wollongong, New South Wales. (josef/[email protected])

*

* The standard is written by A. Zabotin (project leader), G.P. Glazkov,

* and V.B. Isaeva. It was accepted and introduced into use by the

* action of the State Standards Committee of the USSR on 2 June 89 as

* No. 1409. It was to be reviewed in 1993, but whether anyone wishes

* to take on this obligation from the USSR is questionable.

*

* This code is placed in the public domain.

*/


/*

* If you read the standard, it belabors the point of copying corresponding

* bits from point A to point B quite a bit. It helps to understand that

* the standard is uniformly little-endian, although it numbers bits from

* 1 rather than 0, so bit n has value 2^(n-1). The least significant bit

* of the 32-bit words that are manipulated in the algorithm is the first,

* lowest-numbered, in the bit string.

*/



/* A 32-bit data type */

#ifdef __alpha /* Any other 64-bit machines? */unsigned int word32;

#elseunsigned long word32;

#endif


/*

* The standard does not specify the contents of the 8 4 bit->4 bit

* substitution boxes, saying they're a parameter of the network

* being set up. For illustration purposes here, I have used

* the first rows of the 8 S-boxes from the DES. (Note that the

* DES S-boxes are numbered starting from 1 at the msb. In keeping

* with the rest of the GOST, I have used little-endian numbering.

* Thus, k8 is S-box 1.

*

* Obviously, a careful look at the cryptographic properties of the cipher

* must be undertaken before "production" substitution boxes are defined.

*

* The standard also does not specify a standard bit-string representation

* for the contents of these blocks.

*/unsigned char const k8[16] = {

14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }; unsigned char const k7[16] = {

15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 };unsigned char const k6[16] = {

10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 };unsigned char const k5[16] = {

7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 };unsigned char const k4[16] = {

2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 };unsigned char const k3[16] = {

12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 };unsigned char const k2[16] = {

4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 };unsigned char const k1[16] = {

13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 };


/* Byte-at-a-time substitution boxes */unsigned char k87[256];unsigned char k65[256];unsigned char k43[256];unsigned char k21[256];


/*

* Build byte-at-a-time subtitution tables.

* This must be called once for global setup.

*/(void)

{

int i;

for (i = 0; i < 256; i++) {

k87[i] = k8[i >> 4] << 4 | k7[i & 15];

k65[i] = k6[i >> 4] << 4 | k5[i & 15];

k43[i] = k4[i >> 4] << 4 | k3[i & 15];

k21[i] = k2[i >> 4] << 4 | k1[i & 15];

}

}


/*

* Do the substitution and rotation that are the core of the operation,

* like the expansion, substitution and permutation of the DES.

* It would be possible to perform DES-like optimisations and store

* the table entries as 32-bit words, already rotated, but the

* efficiency gain is questionable.

*

* This should be inlined for maximum speed

*/

#if __GNUC__

__inline__

#endifword32(word32 x)

{

/* Do substitutions */

#if 0

/* This is annoyingly slow */

x = k8[x>>28 & 15] << 28 | k7[x>>24 & 15] << 24 |

k6[x>>20 & 15] << 20 | k5[x>>16 & 15] << 16 |

k4[x>>12 & 15] << 12 | k3[x>> 8 & 15] << 8 |

k2[x>> 4 & 15] << 4 | k1[x & 15];

#else

/* This is faster */

x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 |

k43[x>> 8 & 255] << 8 | k21[x & 255];

#endif


/* Rotate left 11 bits */

return x<<11 | x>>(32-11);

}


/*

* The GOST standard defines the input in terms of bits 1..64, with

* bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].

*

* The keys are defined similarly, with bit 256 being the msb of key[7].

*/(word32 const in[2], word32 out[2], word32 const key[8])

{

register word32 n1, n2; /* As named in the GOST */


n1 = in[0];

n2 = in[1];


/* Instead of swapping halves, swap names each round */

n2 ^= f(n1+key[0]);

n1 ^= f(n2+key[1]);

n2 ^= f(n1+key[2]);

n1 ^= f(n2+key[3]);

n2 ^= f(n1+key[4]);

n1 ^= f(n2+key[5]);

n2 ^= f(n1+key[6]);

n1 ^= f(n2+key[7]);


n2 ^= f(n1+key[0]);

n1 ^= f(n2+key[1]);

n2 ^= f(n1+key[2]);

n1 ^= f(n2+key[3]);

n2 ^= f(n1+key[4]);

n1 ^= f(n2+key[5]);

n2 ^= f(n1+key[6]);

n1 ^= f(n2+key[7]);


n2 ^= f(n1+key[0]);

n1 ^= f(n2+key[1]);

n2 ^= f(n1+key[2]);

n1 ^= f(n2+key[3]);

n2 ^= f(n1+key[4]);

n1 ^= f(n2+key[5]);

n2 ^= f(n1+key[6]);

n1 ^= f(n2+key[7]);


n2 ^= f(n1+key[7]);

n1 ^= f(n2+key[6]);

n2 ^= f(n1+key[5]);

n1 ^= f(n2+key[4]);

n2 ^= f(n1+key[3]);

n1 ^= f(n2+key[2]);

n2 ^= f(n1+key[1]);

n1 ^= f(n2+key[0]);


/* There is no swap after the last round */

out[0] = n2;

out[1] = n1;

}



/*

* The key schedule is somewhat different for decryption.

* (The key table is used once forward and three times backward.)

* You could define an expanded key, or just write the code twice,

* as done here.

*/(word32 const in[2], word32 out[2], word32 const key[8])

{

register word32 n1, n2; /* As named in the GOST */


n1 = in[0];

n2 = in[1];


n2 ^= f(n1+key[0]);

n1 ^= f(n2+key[1]);

n2 ^= f(n1+key[2]);

n1 ^= f(n2+key[3]);

n2 ^= f(n1+key[4]);

n1 ^= f(n2+key[5]);

n2 ^= f(n1+key[6]);

n1 ^= f(n2+key[7]);


n2 ^= f(n1+key[7]);

n1 ^= f(n2+key[6]);

n2 ^= f(n1+key[5]);

n1 ^= f(n2+key[4]);

n2 ^= f(n1+key[3]);

n1 ^= f(n2+key[2]);

n2 ^= f(n1+key[1]);

n1 ^= f(n2+key[0]);


n2 ^= f(n1+key[7]);

n1 ^= f(n2+key[6]);

n2 ^= f(n1+key[5]);

n1 ^= f(n2+key[4]);

n2 ^= f(n1+key[3]);

n1 ^= f(n2+key[2]);

n2 ^= f(n1+key[1]);

n1 ^= f(n2+key[0]);


n2 ^= f(n1+key[7]);

n1 ^= f(n2+key[6]);

n2 ^= f(n1+key[5]);

n1 ^= f(n2+key[4]);

n2 ^= f(n1+key[3]);

n1 ^= f(n2+key[2]);

n2 ^= f(n1+key[1]);

n1 ^= f(n2+key[0]);


out[0] = n2;

out[1] = n1;

}


/*

* The GOST "Output feedback" standard. It seems closer morally

* to the counter feedback mode some people have proposed for DES.

* The avoidance of the short cycles that are possible in OFB seems

* like a Good Thing.

*

* Calling it the stream mode makes more sense.

*

* The IV is encrypted with the key to produce the initial counter value.

* Then, for each output block, a constant is added, modulo 2^32-1

* (0 is represented as all-ones, not all-zeros), to each half of

* the counter, and the counter is encrypted to produce the value

* to XOR with the output.

*

* Len is the number of blocks. Sub-block encryption is

* left as an exercise for the user. Remember that the

* standard defines everything in a little-endian manner,

* so you want to use the low bit of gamma[0] first.

*

* OFB is, of course, self-inverse, so there is only one function.

*/


/* The constants for addition */

#define C1 0x01010104

#define C2 0x01010101

(word32 const *in, word32 *out, int len,

word32 const iv[2], word32 const key[8])

{

word32 temp[2]; /* Counter */

word32 gamma[2]; /* Output XOR value */


/* Compute starting value for counter */

gostcrypt(iv, temp, key);


while (len--) {

temp[0] += C2;

if (temp[0] < C2) /* Wrap modulo 2^32? */

temp[0]++; /* Make it modulo 2^32-1 */

temp[1] += C1;

if (temp[1] < C1) /* Wrap modulo 2^32? */

temp[1]++; /* Make it modulo 2^32-1 */


gostcrypt(temp, gamma, key);


*out++ = *in++ ^ gamma[0];

*out++ = *in++ ^ gamma[1];

}

}


/*

* The CFB mode is just what you'd expect. Each block of ciphertext y[] is

* derived from the input x[] by the following pseudocode:

* y[i] = x[i] ^ gostcrypt(y[i-1])

* x[i] = y[i] ^ gostcrypt(y[i-1])

* Where y[-1] is the IV.

*

* The IV is modified in place. Again, len is in *blocks*.

*/

(word32 const *in, word32 *out, int len,

word32 iv[2], word32 const key[8])

{

while (len--) {

gostcrypt(iv, iv, key);

iv[0] = *out++ ^= iv[0];

iv[1] = *out++ ^= iv[1];

}

}

(word32 const *in, word32 *out, int len,

word32 iv[2], word32 const key[8])

{

word32 t;

while (len--) {

gostcrypt(iv, iv, key);

t = *out;

*out++ ^= iv[0];

iv[0] = t;

t = *out;

*out++ ^= iv[1];

iv[1] = t;

}

}



/*

* The message suthetication code uses only 16 of the 32 rounds.

* There *is* a swap after the 16th round.

* The last block should be padded to 64 bits with zeros.

* len is the number of *blocks* in the input.

*/(word32 const *in, int len, word32 out[2], word32 const key[8])

{

register word32 n1, n2; /* As named in the GOST */


n1 = 0;

n2 = 0;


while (len--) {

n1 ^= *in++;

n2 = *in++;


/* Instead of swapping halves, swap names each round */

n2 ^= f(n1+key[0]);

n1 ^= f(n2+key[1]);

n2 ^= f(n1+key[2]);

n1 ^= f(n2+key[3]);

n2 ^= f(n1+key[4]);

n1 ^= f(n2+key[5]);

n2 ^= f(n1+key[6]);

n1 ^= f(n2+key[7]);


n2 ^= f(n1+key[0]);

n1 ^= f(n2+key[1]);

n2 ^= f(n1+key[2]);

n1 ^= f(n2+key[3]);

n2 ^= f(n1+key[4]);

n1 ^= f(n2+key[5]);

n2 ^= f(n1+key[6]);

n1 ^= f(n2+key[7]);

}


out[0] = n1;

out[1] = n2;

}


#ifdef TEST


#include <stdio.h>

#include <stdlib.h>


/* Designed to cope with 15-bit rand() implementations */

#define RAND32 ((word32)rand() << 17 ^ (word32)rand() << 9 ^ rand())

(void)

{

word32 key[8];

word32 plain[2];

word32 cipher[2];

int i, j;


kboxinit();


printf("GOST 21847-89 test driver.\n");


for (i = 0; i < 1000; i++) {

for (j = 0; j < 8; j++)

key[j] = RAND32;

plain[0] = RAND32;

plain[1] = RAND32;


printf("%3d\r", i);

fflush(stdout);


gostcrypt(plain, cipher, key);

for (j = 0; j < 99; j++)

gostcrypt(cipher, cipher, key);

for (j = 0; j < 100; j++)

gostdecrypt(cipher, cipher, key);


if (plain[0] != cipher[0] || plain[1] != cipher[1]) {

fprintf(stderr, "\nError! i = %d\n", i);

return 1;

}

}

printf("All tests passed.\n");

return 0;

}


#endif /* TEST */







Простое XOR



//**************************************

//INCLUDE files for :crypt.c

//**************************************

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>


//**************************************

// Name: crypt.c

// Description:Encrypts file and outputs it to a file or stdout

// By:

//

//

// Inputs:crypt1.exe <infile> <outfile> <key>

//

//**************************************


#define cypherbits 256 /* encryption strength in bits */

#define cypher cypherbits/(sizeof(int)*8)seed[cypher];modseed() {x;(x=1;x<cypher;x++)seed[x]=seed[x]*0x81772012+seed[x]+0x49122035+seed[x+1];(x=1;x<cypher;x++)seed[0]=seed[0]^seed[x];

}seedsum() {n,x;=0x80379251;(x=0;x<cypher;x++)n=n^seed[x];((n>>24)^((n>>16)&255)^((n>>8)&255)^(n&255));

}strequ(char *s1,char *s2) {p;=0;((s1[p]==s2[p])&&(s1[p]!=0)&&(s2[p]!=0))p++;(s1[p]==s2[p])return(1); else return(0);

}main(int argc,char *argv[]) {banner[]="\x43\x6f\x64\x65\x64\x20\x62\x79\x20\x70\x61\x69"

"\x6e\x74\x20\x6f\x66\x20\x44\x61\x6c\x4e"

"\x75\x74\x20\x28\x70\x61\x69\x6e\x74\x40\x6c\x65\x65\x74\x2e\x63\x6f\x6d\x29";buf[2048];p,r,l,i,t,s,x;b,c,pct,lpct;*infile=NULL,*outfile=NULL;(stderr, "%s\n", banner);(argc!=4){(stderr,"use: %s <infile> <outfile> <key>\n",argv[0]);(-1);

}(strequ(argv[1],"stdin"))infile=stdin; else((infile=fopen(argv[1],"r"))==NULL){(stderr,"failed to open %s\n",argv[1]);(-1);

}(strequ(argv[2],"stdout"))outfile=stdout; else((outfile=fopen(argv[2],"w"))==NULL){(stderr,"failed to create %s\n",argv[2]);(-1);

}(infile!=stdin) {(infile,0,SEEK_END);=ftell(infile);(infile);

} else l=0;=l;=0;=0;(l<1)fprintf(stderr,"Encrypting data.. (%d bit cypher)\n",cypher*sizeof(int)*8);fprintf(stderr,"Encrypting %d bytes.. (%d bit cypher)\n",l,cypher*sizeof(int)*8);(seed,sizeof(seed));;=0;(argv[3][p]!=0){;[0]=seed[0]+argv[3][p];;++;

}=0;(l>0){('[',stderr);=(l/sizeof(buf));(l-x*sizeof(buf)!=0)x+=1;(x>38)x=38;(p=0;p<x;p++) fputc(32,stderr);(']',stderr);(13,stderr);('[',stderr);(stderr);

}=1;(c){=fread(&buf,1,sizeof(buf),infile);(r>0) {

t+=r;

if(l>0){

lpct=pct;

pct=t/(l/x);

if(pct>lpct) {

fputc(88+32*i,stderr);

fflush(stderr);

i=1-i;

}

} else {

fputc(88+32*i,stderr);

fflush(stderr);

i=1-i;

}

p=0;

while(p<r) {

modseed();

buf[p]=buf[p]^seedsum();

p++;

}

if(fwrite(&buf,1,r,outfile)!=r) {

fprintf(stderr,"\nerror writing data\n");

exit(-1);

}

} else c=0;

}(l>0)fputc(']',stderr);(stderr,"\nDone. Wrote %d bytes.\n",t);

}


FileCoding



Данная программа осуществляет простое (без сжатия) кодирование любого файла по алгоритму ГОСТ. ГОСТ был выбрано по нескольким причинам- одна из которых, возможное принятие данного алгоритма шифрования в качестве основного, Соединенными Штатами Америки, а следовательно (так как он уже признан стандартом шифрования России)-данный алгоритм является на данный момент самым надежным и легко реальзуемым

Для работы с программой для начала необходимо дважды ввести пароль (не менее 3-х символов, рекомендуется более) и задём нажатием на кнопку «rjlbht,f» вызвать диалоговое окно выбора файла. Далее фаил будет закодирован и сохранен под тем же именем что и исходный, но с расширением *.enc. Рекомендуется удалять исходный фаил.

Процесс раскодирование похож на процесс кодирование с точностью до наоборот- тоесть надо ввести (дважды) пароль, нажать «ltrjlbht,f», и затем выбрать зашифрованный фаил. После выдачи системного сообщения «Процесс завершён», раскодированный фаил становится доступным.


ДИПЛОМНАЯ РАБОТА ОСНОВЫ КРИПТОГРАФИИ Оглавление криптография протокол алгоритм ключ Введ

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ