Разработка и реализация математической модели двухключевой криптосистемы

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

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 14.08.2015
Размер файла 390,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

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

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

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

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

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

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

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

В этом случае проблема состоит в том, чтобы надёжно удостоверить подлинность субъектов.

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

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

возможность отказа от центра распределения ключей

взаимное подтверждение подлинности участников сеанса

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

Криптографический анализ асимметричных систем шифрования

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

С помощью открытого ключа шифрования пользователь i шифрует сообщение М и посылает пользователю j по незащищенному каналу передачи данных. Только пользователь j может выполнить дешифрование, чтобы восстановить M, поскольку только он знает секретный ключ дешифрования.

Среди асимметричных (открытых) криптосистем наиболее широкое распространение получила криптографическая система RSA. В этой системе получатель сообщения выбирает два больших простых числа p и q так, чтобы произведение n = pq находилось за пределами вычислительных возможностей. Исходное сообщение М может иметь произвольную длину в диапазоне 1<M<n. Шифрованный текст C, соответствующий сообщению М, может быть получен в виде

C Me (mod n) .

Исходный текст М восстанавливается из шифрованного C обратным преобразованием

M Cd (mod n) .

Получатель выбирает e и d так, чтобы выполнялись условия:

(e, ) = 1

ed 1 (mod )

где - функция Эйлера, равная (p - 1)(q - 1);

(a, b) - наибольший общий делитель двух чисел.

То есть e и d являются в мультипликативной группе обратными величинами в арифметике вычетов по mod .

Очевидно, что главной целью криптографического раскрытия является определение секретного ключа (показателя степени при C - значения d).

Известны три способа, которыми мог бы воспользоваться криптоаналитик, для раскрытия величины d по открытой информации о паре {e, n}.

Факторизация n

Разложение величины n на простые множители позволяет вычислить функцию и, следовательно, скрытое значение d, используя уравнение

ed 1 (mod ).

Различные алгоритмы такого разложения изложены в [1]. Наиболее быстрый алгоритм, известный в настоящее время, может выполнить факторизацию n за число шагов порядка

(ln n) .

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

Прямое вычисление

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

x = p + q = n + 1 - ,

y = (p - q)2 = x2 - 4n.

Зная , можно определить x и, следовательно, y, зная x и y, простые p и q можно определить из следующих соотношений:

p = ,

q = .

Прямая оценка d

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

ed - 1 = k,

где k - произвольное целое число.

Факторизацию n можно выполнить, используя любое значение, кратное [1]. Дешифровщик, с другой стороны, может попытаться найти некоторую величину d', которая была бы эквивалентна скрытой величине d, использованной при разработке шифра. Если существует много таких d', то можно попытаться использовать прямой перебор, чтобы раскрыть шифр. Но все d' различаются множителем, равным [p-1, q-1] и если этот множитель вычислен, то n можно факторизовать. Таким образом, нахождение d столь же сложно, что и факторизация n.

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

пусть нам дано целое число n>0, и требуется, если это возможно, найти два числа a и b, таких, что ab = n. На самом деле имеются две различные задачи: первая, называемая тестом на простоту - это проверка того, существуют ли такие a и b; вторая, называемая разложением - это задача их нахождения. Рассмотрим обе эти задачи.

Первый детерминистический тест.

Этот тест основан на малой теореме Ферма, которая утверждает, что если p - простое число, то ap-1 1 (mod p) для всех a, 1<a<p.

Таким образом, тест состоит в выборе числа а, меньшего b и проверке

b на принадлежность классу простых чисел согласно условию ab-1 1 (mod b) в соответствии с приведенным выражением. Практически требуется проверить только несколько значений a. Выбор а, равным 3, позволяет выявить все составные числа. Тем не менее известно, что этот тест пропускает составные числа Кармайкла (например число 561 =3 х 11 х 17).

Рекомендуется порядка 100 тестов, чтобы надежно убедиться, что данное число простое.

Второй детерминистический тест.

Разделим число “b” последовательно на 2, 3, ..., . Если при каком-нибудь делении мы получим нулевой остаток, то число “b” составное, а делитель и частное являются его сомножителями; в противном случае b - простое.

Поскольку необходимо выполнить делений, то время проверки простоты числа “b” равно O().

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

Третий детерминистический тест.

Число “b” просто тогда и только тогда, когда b | {(b-1)! + 1}. Факториал (b-1)! и проверка делимости (b-1)!+1 для больших “b” уничтожает всякий интерес к этому тесту. Если `b' имеет 100 десятичных цифр, то (b-1)! состоит примерно из 100102 цифр.

Все приведенные выше тесты были детерминистическими. Это означает, что для заданного числа “b” мы всегда получаем ответ, является ли оно простым или составным. Если заменить слово «всегда» на «с некоторой вероятностью», то оказывается возможным построить вероятностные тесты, которые называют также тестами псевдопростоты.

Первый вероятностный тест.

Этот тест позволяет выявить все составные числа Кармайкла. Выбирается случайное число a в диапазоне от 1 до b-1 и проверяется выполнение условий.

(a, b) = 1, J(a, b) a(b-1)/2 (mod b),

где J(a, b) символ Якоби.

Символ Якоби определяется следующими соотношениями:

J(a, p) = 1, если x2 a (mod p) имеет решения в Zp,

J(a, p) = -1, если x2 a (mod p) не имеет решения в Zp,

где Zp - кольцо вычетов по модулю p.

Если b - простое число, условия приведенные выше, всегда выполняются, а если b - составное, то они не выполняются с вероятностью . Поэтому выполнение k тестов гарантирует, что ответ неправилен с вероятностью 2-k.

Второй вероятностный тест.

Поскольку число b, которое должно быть простым, всегда нечетное, то его можно представить в виде

b = 2rs + 1,

где s - четное число. Затем в тесте выбирается случайным образом число a в диапазоне от 1 до b-1 и проверяется выполнение условий

as 1 (mod b),

-1 (mod b) для 0 < j <r.

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

Третий вероятностный тест.

Для заданного b выбираем случайным образом m, 1<m<b. Если m | b, то тест выдает ответ “b - составное число”, в противном случае - "не удалось определить".

Вероятность того, что выдается ответ “b - составное число”, равна вероятности того, что m | b. Если d(b) число делителей b и m - случайно выбрано в пределах 1<m<b, то вероятность этого равна p = [d(b) - 2]/b.

Это очень слабый тест.

Четвертый вероятностный тест.

Для заданного “b” выбираем случайным образом m, 1<m<b. Если (b, m)1, то тест выдает ответ “b - составное число”, в противном случае - "не удалось определить".

Если b составное число, то количество чисел m<b, для которых тест выдает ответ “b - составное число”, равно b - . Это число велико, если b имеет маленькие простые делители. Если b = pq, где p, q - большие простые числа, то вероятность того, что число b -- простое очень мала и поэтому этот тест не лучше предыдущего.

Пятый вероятностный тест.

Это тест сильной псевдопростоты. Пусть заданы b и m. Пусть

b- 1 = t2S,

где t - нечетное число и рассмотрим числа для (xr - наименьший по абсолютной величине остаток по модулю b).

Если либо x0 = 1, либо найдется индекс i, i<S, такой, что хi = 1, то b называется сильно псевдопростым по основанию m и тест выдает ответ "не удалось определить", в противном случае ответ b составное число. Этот тест успешно применяется и к псевдопростым числам, таким как b=561. Если тест сильной псевдопростоты выдает ответ “b - составное число”, то b - составное число.

Докажем это от противного. Предположим, что b - нечетное простое число. Покажем по индукции, что 1 (mod b) для , что будет противоречить условию теоремы.

Очевидно, что это справедливо для r = S по теореме Ферма. Предполагая справедливость утверждения для i, нетрудно видеть, что оно справедливо для i-1, потому что равенство

влечет за собой, что возводимое в квадрат число равно ±1. Но -1 не подходит по условию (иначе бы тест выдал ответ "не удалось определить").

Доказано, что если b - составное число, то вероятность того, что тест выдаст ответ "b - составное число" не меньше [1].

Разложение на множители больших целых чисел.

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

Метод основывается на идее Лежандра, если U2 V2 (mod b) 0<U, V<b, U V(mod b), то b делит (U - V)(U + V), но не делит ни (U - V), ни (U + V); поэтому (U-V, b) - наибольший общий делитель чисел U-Vи b, является нетривиальным делителем b и может быть легко вычислен с помощью алгоритма Евклида. Поиск таких U и V происходит в два этапа.

Пусть мы хотим разложить на множители число b. Пусть n = - максимальное число, не превосходящее , и вычислим числа ak = (n + k)2 - b для небольших k (числа k могут быть и отрицательными).

Пусть {qi, i = 1, 2, …, j} - множество небольших простых чисел, которые могут делить выражение вида x2 - b (т.е. b является квадратом по модулю qi). Такое множество обычно называется мультипликативной базой В. Запомним все числа ak, которые могут быть разложены по мультипликативной базе, т.е. записаны в виде

.

Такие ak называются В-числами. С каждым В-числом ak связывается вектор показателей

Если мы найдем достаточно много В-чисел, чтобы множество соответствующих векторов показателей было линейно зависимо по модулю 2

(любое множество из j+2 В-чисел обладает этим свойством), то можно будет представить нулевой вектор в виде суммы векторов показателей некоторого множества S, скажем

Определим целые числа

i = 0, 1, …, j,

,

.

Из сказанного выше следует, что U2 V2(mod b) и (U-V, b) может быть нетривиальным делителем b.

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

Сej(mod n)=C.

Т. е. противник просто проводит j раз зашифрование на открытом ключе перехваченного шифротекста. Это выглядит следующим образом: (Сe)e)e..)e(mod n)=Сej(mod n)). Найдя такое j, противник вычисляет Ce(j-1)(mod n) (т.е. j-1 раз повторяет операцию зашифрования) - это значение и есть открытый текст M. Это следует из того, что Сej(mod n)=(Ce(j-1)(mod n))e=C. Т. е. некоторое число Ce(j-1)(mod n) в степени e дает шифротекст С. А это открытый текст M.

Пример. p=983, q=563, e=49, M=123456.

C=M49(mod n)=1603, C497(mod n)=85978, C498(mod n)=123456, C499(mod n)=1603.

5. Работа с программой RSA

5.1 Описание программы

Программа, разработанная в среде Delphi 4, представляет собой проект с названием RSA.dpr и содержит 8 программных модулей (*.pas) и 8 соответствующих им форм (*.dfm). Опишем их более подробно:

Таблица 3

Модули (*.pas)

Формы (*.dfm)

Назначение

MainProg

MainForm

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

About

AboutBox

Информационное окно. Форма появляется при выборе пункта меню Help/About.

Cipher, Decipher

CipherForm, DecipherForm

Формы и модули, визуально отражающие количество зашифрованной (расшифрованной) информации. Форма появляется при выборе пунктов главного меню Work/Cipher или Work/Decipher.

Wait

WaitForm

Форма появляется на экране во время выполнения процедуры генерации ключей и содержит предупреждение о длительности генерации.

Choose

ChooseForm

Выбор теста простоты. Форма появляется перед генерацией ключей при выборе пункта главного меню Work/Keys_Generation.

AntiRSA

AntiR

Модуль содержит процедуры, реализующие раскрытие шифра RSA дешифрованием итерациями. Форма появляется при выборе пункта главного меню AntiRSA.

Help

HelpForm

Помощь в работе с программой. В окне редактора формы содержатся необходимые инструкции для работы. Форма появляется при выборе пункта главного меню Help/Help.

Опишем более подробно процедуры генерации ключей.

При выборе пункта Work/Keys_Generation простые числа p и q генерируются псевдослучайно. P, q проверяются на простоту с помощью вероятностного или детерминированного теста. Далее числа переводятся в десятичную систему счисления. Вычисляется их произведение n = p * q и функция Эйлера = (p - 1)(q - 1). Так как ключи записываются в файлы при каждом вызове процедуры генерации и в программе предусмотрена возможность использования ключей из файла, некоторые элементы шифрации и дешифрации вычисляются здесь же и записываются в файлы Secret и UnSecret соответственно. Это секретный ключ d: ed 1 (mod n) (используемый для дешифрации) и открытый ключ e: (e, ) = 1.

Шифрация происходит следующим образом: каждый символ исходного текста представляется своим кодом в таблице ASCII-кодов. Далее программа работает с этим кодом как с числом, представленным в виде строки. Зашифрованное сообщение S'=SE mod N представляет собой строку, которая записывается в файл Cipher. Таким образом, файл Cipher состоит из строк, каждая из которых является зашифрованным символом исходного текста.

При дешифрации последовательно обрабатываются строки файла Cipher: S=S'E mod N. Полученное S представляет собой код ASCII. По нему несложно получить символ исходного текста.

Процедура дешифрования итерациями состоит в следующем: зашифрованный текст M последовательно шифруется с помощью открытого ключа, пока снова не будет получено M. Если это произошло на i+1 итерации, то результат, полученный на i итерации, и будет исходным сообщением [7], т. е. M1 = M, …, Mi+1 = (Mi)Е mod N, где Е - открытый ключ, N - модуль (произведение двух простых чисел). Если Mi+1 = M, то Mi - исходный текст.

5.2 Требования к техническим средствам и шифруемым файлам

Для нормальной работы программы необходим компьютер Pentium с объемом диска 1Гб , 16 Мб ОП и тактовой частотой 100 МГц. Требования к операционной системе: Windows-98 или Windows NT.

Программа вместе с необходимыми ей файлами ключей устанавливается в каталог New_RSA в любое место диска. Возможна работа программы как из среды Delphi 4(5), так и при отсутствии среды программирования при наличии файла RSA.exe.

Программа RSA зашифровывает файлы с расширением *.txt или без расширения, содержащие текстовую информацию. Любой символ файла будет интерпретирован как текст по таблице ASCII-кодов. Поэтому файлы, использующие другую кодировку, будут обработаны неправильно.

5.3 Вычислительный эксперимент

В программе RSA реализована возможность шифрации как существующих на диске, так и созданных во время работы с программой файлов. Запуск программы можно осуществить двумя способами: запустить файл RSA.exe из командной строки или, находясь в среде программирования Delphi, открыть файл проекта RSA.dpr и выполнить команду Run (F9). На экране появляется главная форма (рис. 1).

Рис. 1. Главная форма программы RSA

Пункт меню File содержит подпункты Open, Save, Save_as, Close для работы с файлами. Выберем пункт File\Open. На экране появляется диалоговое окно выбора файла (рис. 2).

Рис. 2. Диалоговое окно выбора файла

Выбираем из списка предложенных файлов Test2 и нажимаем Open. В окне главной формы появляется текст файла (рис. 3).

Рис. 3. Главная форма, содержащая текст выбранного файла

Заметим, что пункты главного меню Work/Cipher, Work/Decipher недоступны для выбора. Теперь можно выбрать Work/FromFile. Опция Work/Cipher стала доступна: выберем ее. Шифрация началась и на экране появилось окно, отображающее количество зашифрованных данных (рис. 4).

Рис. 4. Окно-индикатор процесса шифрации

При завершении шифрации текст в окне редактора главной формы приобрел следующий вид (рис. 5).

Рис. 5. Зашифрованный текст в окне главной формы

Заметим, что опция Work/Decipher стала доступной для выбора (возможна также запись зашифрованного файла на диск с помощью пункта меню File/Save_as). Выберем ее, чтобы расшифровать сообщение. На экране появится окно, отображающее количество дешифрованных данных (рис. 6).

Рис. 6. Окно-индикатор процесса дешифрации

Расшифровать можно также любой файл, ранее зашифрованный этой программой. Для этого следует открыть его (File/Open) и выбрать пункт меню Work/Decipher. В результате дешифрации в окне появляется дешифрованное сообщение (рис. 7).

Рис. 7. Результат дешифрации в окне главной формы

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

Рис. 8. Сообщение об ошибке при попытке некорректной дешифрации

Рассмотрим другие возможности программы.

При выборе пункта меню Work/Keys_Generation появляется окно выбора теста простоты (рис. 9).

Рис. 9. Выбор способа проверки числа на простоту

Выбираем вероятностный способ. Начинается генерация ключей. Все время генерации на экране находится предупреждение “процесс генерации может занять несколько минут”. При завершении генерации предупреждение исчезает. Опция Work/Cipher стала доступной для выбора.

Пункт меню AntiRSA демонстрирует возможность раскрытия шифра системы RSA. В данном случае используются следующие ключи:

N = 47053

M = 46620

D = 16813 - открытый ключ

E = 19837 - секретный ключ [7]

При выборе пункта меню AntiRSA на экране появляется окно (рис. 11).

Рис. 11. Форма для взлома шифра RSA

Если выбрать кнопку Взломать или Зашифровать, предварительно не вводя сообщения, на экране появится окно (рис. 12).

Рис. 12. Сообщение об ошибке при отсутствии исходного текста для шифрации

При вводе исходного сообщения (число), следует учитывать, что оно должно быть меньше N, иначе появится следующее сообщение (рис. 13).

Рис. 13. Сообщение об ошибке при величине исходного текста, превышающей длину ключа

Введем сообщение 3456 и выберем кнопку Зашифровать. Зашифрованное сообщение появится в окне (рис. 14).

Рис. 14. Результат шифрации

Теперь можно выбрать кнопку Взломать и наблюдать за результатами взлома. Число итераций, необходимых для взлома, и результаты итераций отображаются на экране (рис. 15).

Для получения краткой информации о программе можно выбрать пункт меню Help/About. На экране появится форма (рис. 16).

Для получения справки о работе с программой следует выбрать пункт меню Help/Help. На экране появится форма (рис. 17).

Рис. 15. Результат взлома шифра RSA

Рис. 16. Форма, содержащая краткую информацию о программе

Рис. 17. Форма, содержащая справочную информацию о возможностях программы и особенностях работы с ней

Здесь можно найти справочную информацию о программе.

Исходный текст занимает места больше, чем это необходимо - обладает большой избыточностью, как всякий текст на родном языке. При хорошей шифрации избыточность уменьшается. Сжатие текста архиваторами также устраняет избыточность. Если текст шифровки сжимается одним из архиваторов больше, чем на 10 %, то шифровальная система не состоятельна. Алгоритмам архивирования удается сжимать даже случайные последовательности символов, хотя сжатие в этом случае не превышает единиц процентов [7].

Вычислительный эксперимент показал следующие соотношения:

При использовании архиватора ARJ исходный текст сжимается на 48,6 %; зашифрованный файл сжимается на 1 %.

При использовании архиватора RAR исходный текст сжимается на 51,09 %; зашифрованный файл сжимается на 1,04 %.

При использовании архиватора ZIP исходный текст сжимается на 51,31 %; зашифрованный файл сжимается на 0,93 %.

Заключение

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

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

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

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

Разработана программа, реализующая схему шифрования RSA, с возможностью шифрации и дешифрации файлов, использующих кодировку ASCII. Программа разработана в среде программирования Delphi 4 на языке Object Pascal.

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

Главным достоинством криптосистем с открытым ключом является их потенциально высокая безопасность: нет необходимости ни передавать, ни сообщать кому-либо значение секретных ключей, ни убеждаться в их подлинности [6].

Алгоритм криптосистемы с открытым ключом можно использовать в трёх направлениях.

Как самостоятельные средства защиты передаваемых и хранимых данных

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

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

Однако алгоритмы, лежащие в основе криптосистем с открытым ключом, имеют следующие недостатки:

генерация новых секретных и открытых ключей основана на генерации новых больших простых чисел, а проверка простоты чисел занимает много машинного времени;

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

Для практической реализации алгоритмов RSA полезно знать оценки трудоёмкости разложения простых чисел различной длины, сделанные Шроппелем [2].

Таблица 4

lg n

Число операций

Примечания

50

1.4* 1010

Раскрываем на суперкомпьютерах

100

2,3* 1015

На пределе современных технологий

200

1.2 * 1023

За пределами современных технологий

400

2.7 * 1034

Требует существенных изменений в технологии

800

1.3 * 1051

Не раскрываем

Сами авторы RSA рекомендуют использовать следующие размеры модуля n:

768 бит - для частных лиц

1024 бит - для коммерческой информации

2048 бит - для особо секретной информации

Данные оценки сделаны с учётом развития вычислительной техники вплоть до 2004 года.

В настоящее время алгоритм RSA активно реализуется как в виде самостоятельных криптографических продуктов, так и в качестве встроенных средств в популярных приложениях (в браузерах Интернет от Microsoft и Netscape) .

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

мультипликативный криптосистема шифрование

Список использованных источников

А.Г. Акритас Основы компьютерной алгебры с приложениями: пер. с венгерского. - М.: Мир, 1994. - 456 с.

Компьютерная алгебра. Символьные и алгебраические вычисления / Под ред. Б. Бухбергер, Дж. Коллинз, Р. Лоос , М.: Мир, 1986. - 557 с.

Виноградов И. М. Основы теории чисел - М.: Наука, 1981. - 176 с.

Баричев С. Криптография без секретов., 1998. - 43 c.

Нечаев В.И. Элементы криптографии: Основы теории защиты информации: Учебное пособие. - М.: Высшая школа, 1999. - 108 с.

Воронков Б.Н., Тупота В.И. Методическое пособие по разработке средств защиты информации в вычислительный сетях. - Воронеж: Типография ВГУ, 2000. - 112 с.

Жельников В. Криптография от папируса до компьютера. - М.:ABF, 1996. - 336 с.

Романец Ю.В., Тимофеев П.А., Шаньгин В.Ф. Защита информации в компьютерных системах и сетях / Под ред. В.Ф. Шаньгина. - М.: Радио и связь, 1999. - 328 с.

Кузьминский М. Повседневные средства безопасной работы// Открытые системы, 2000, №12. - 12 - 19 с.

Введение в криптографию / Под общ. ред. Ященко В.В. - М.:МЦНМО, “ЧеРо”, 1998. - 272 с.

Приложение 1

Текст основной программы RSA

unit MainProg;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, Menus;

const

IC=76; {76 бит в шифр-коде}

HC=75; {75 бит в коде Хэмминга}

WL=152; {152 бит в общем слове}

SKD=64; {64 бит в секретном ключе}

type

Dkey=record {тип-несекретные ключи}

N:string; {N-произведение двух простых чисел}

E:string; {E-взаимно простое с функцией Эйлера от N}

end;

Skey=record {тип-секретные ключи}

P:string; {P-простое число}

Q:string; {Q-простое число}

D:string; {D-мультипликатив. обратное к Е по модулю

ф.Эйлера от N}

end;

TMainForm = class(TForm)

MainMenu1: TMainMenu;

File1: TMenuItem;

Work1: TMenuItem;

AntiRSA1: TMenuItem;

Help1: TMenuItem;

Close1: TMenuItem;

Open1: TMenuItem;

Save1: TMenuItem;

Saveas1: TMenuItem;

Close2: TMenuItem;

FromFile1: TMenuItem;

KeysGeneration1: TMenuItem;

Cipher1: TMenuItem;

Decipher1: TMenuItem;

About1: TMenuItem;

Help2: TMenuItem;

Memo1: TMemo;

OpenDialog1: TOpenDialog;

SaveDialog1: TSaveDialog;

procedure Open1Click(Sender: TObject);

procedure Close1Click(Sender: TObject);

procedure Save1Click(Sender: TObject);

procedure Saveas1Click(Sender: TObject);

procedure About1Click(Sender: TObject);

procedure AntiRSA1Click(Sender: TObject);

procedure KeysGeneration1Click(Sender: TObject);

procedure FromFile1Click(Sender: TObject);

function Bol(a1,b1:string):integer;

procedure Deln(a3:string);

function Sum(a2,b2:string):string;

function Mins(a5,b5:string):string;

function Umn(a4,b4:string):string;

function Divis(a6,b6:string):string;

function Modulo(a7,b7:string):string;

procedure Hamcode;

procedure Dhamm;

function Recod:string;

function Der1(a11,b11,c11:string):string;

procedure GenKeys;

procedure Cipher1Click(Sender: TObject);

procedure Decipher1Click(Sender: TObject);

procedure Help2Click(Sender: TObject);

procedure Close2Click(Sender: TObject);

procedure FormActivate(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

MainForm: TMainForm;

KeyFlag, Cipflag: boolean;

b:array[0..IC]of string; {массив двоичных кодов}

coderc:array[0..IC]of boolean; {информационный код}

hamming:array[0..HC]of boolean; {код Хэмминга}

prmx:array[0..IC,0..HC]of boolean; {порождающая матрица кода Хэмминга}

prmx1:array[0..HC,0..WL]of boolean; {проверочная матрица кода Хэмминга}

incode:array[0..WL]of boolean; {входной код на приемном блоке}

skbin:packed array[0..skd]of boolean; {бинарный код секретного ключа}

esbin:packed array[0..skd*2]of boolean; {бинарный код несекретного ключа}

security:Skey; {запись-секретные ключи}

dkeys:Dkey; {запись-несекретные ключи}

Sekret:File; {файл секретных ключей}

UnSekret:File; {файл несекретных ключей}

km,wer:longint; {число ошибок в принятом слове}

eyl:string; {функция Эйлера}

f1,f3:file of char; {исходный файл, дешифрованный файл}

f2:TextFile; {шифрованный файл}

id,jd:integer; {счетчик}

temp,cp:integer; {переменная для ASCII-кодов}

tc1:string; {переменная для ASCII-кодов}

ftest:boolean; {флаг метода теста числа на простоту

1 - вероятностный, 0 - детерминированный}

ch:char; {считываемый символ}

implementation

uses Decipher, Cipher, Choose, AntiRSA, Wait, About, Help;

function TMainForm.Bol(a1,b1:string):integer;{Сравнение абсолютных величин

a1 и b1 <0-'=', 1-'>', 2-'<'>}

var

f:integer; {переменная сравнения}

sd1,sd2:integer; {сравниваемые цифры - тип <целое>}

sr1,sr2:string[1]; {сравниваемые цифры - тип <строчное>}

ks1,ks2:integer; {длины сравниваемых чисел}

cd:integer; {переменная ошибки}

begin

f:=0;

ks1:=length(a1); {запоминаем длину a1}

ks2:=length(b1); {запоминаем длину b1}

while(ks1<>0) or (ks2<>0) do {пока не пройдем самое большое число}

begin

sd1:=0;

sd2:=0;

if ks1>0 then begin

sr1:=copy(a1,ks1,1); {копируем цифру 1-го числа для преобр.}

if sr1<>'-' then val(sr1,sd1,cd); {преобр. цифру 1-го числа в тип}

end; {<целое>}

if ks2>0 then begin

sr2:=copy(b1,ks2,1);

if sr2<>'-' then val (sr2,sd2,cd);{преобр. цифру 2-го числа в тип}

end; {<целое>}

if abs(sd1)>abs(sd2)

then f:=1

else if abs(sd1)<abs(sd2) then f:=2;

if ks1>0 then ks1:=ks1-1;

if ks2>0 then ks2:=ks2-1;

end;

Bol:=f; {значению ф-ции присваиваем значение результир. переменной f}

end;

procedure TMainForm.Deln(a3:string); {удаляем нули спереди}

var

m:boolean; {флаг наличия минуса}

kn,ac:integer; {kn-кол-во нулей спереди, ac-анализируемая цифра числа}

cd:integer; {переменная ошибки процедуры val}

a31:string; {переменная для работы с числом}

begin

a31:=''; {инициализируем a31}

a31:=a3;

if pos('-',a31)<>0 {если <-> в числе есть,}

then m:=true {то m-истина}

else m:=false; {иначе m-ложно}

val(copy(a31,1,1),ac,cd); {копир. в перем. ac анализир. цифру и переприсв.}

{тип-integer}

while (length(a31)>0) do {пока длина строки числа a31 не пустая}

begin

{копир. в перем. ac анализир. цифру и переприсв.}

val(copy(a31,1,1),ac,cd); {тип-integer}

if not((ac>=49)and(ac<=57)) {если ac-ноль, то}

then delete(a31,1,1); {из строки a31 удалить 1-й символ}

end;

if m then a31:='-'+a31; {если в числе есть минус, то добавить его}

a3:=''; {спереди в результат}

a3:=a31; {инициализируем a3 и возвращаем a3 без нулей спереди}

end;

function TMainForm.Sum(a2,b2:string):string; {суммирование a2+b2}

var

d:integer; {переменная переполнения}

s1,s2:integer; {складываемые цифры чисел a2 и b2 тип-<целое>}

s3:integer; {сумма цифр s1 и s2 тип-<целое>}

cd:integer; {переменная ошибки процедуры val}

ks1,ks2:integer; {длины складываемых чисел a2 и b2}

sk1,sk2:string[1]; {складываемые цифры чисел a2 и b2 тип-<строчное>}

sk3:string[1]; {сумма цифр s1 и s2 тип-<строчное>}

fl:boolean; {флаг смены знака на противоположный}

bb1,bb2,rez,bfr:string; {переменная для выполнения операции <сложение>}

begin

ks1:=length(a2); {загружаем в ks1 длину числа a2}

ks2:=length(b2); {загружаем в ks2 длину числа b2}

rez:=''; {инициализируем результирующую переменную}

if ((pos('-',a2)<>0)and(pos('-',b2)<>0)) or {если a2 и b2 одинаковы по}

((pos('-',a2)=0)and(pos('-',b2)=0)) then {знаку, то}

begin

fl:=false; {флаг смены знака-ложный}

d:=0; {обнуляем переменную переполнения}

while not((ks1=0)and(ks2=0)) do {пока не пройдены все цифры склад.чисел}

begin

s1:=0;

s2:=0;

s3:=0;

sk1:=copy(a2,ks1,1); {вычисляем младшую цифру из a2}

if ks1>0 then {если цифры a2 не пройд., то}

if sk1<>'-' then {если выбранная цифра не минус, то}

val(sk1,s1,cd); {переводим ее в тип <целое>}

sk2:=copy(b2,ks2,1); {вычисляем младшую цифру из a2}

if ks2>0 then {если цифры a2 не пройд., то}

if sk2<>'-' then val(sk2,s2,cd); {переводим ее в тип <целое>}

s2:=abs(s2)+d; {прибавляем ко 2-му слаг. перемен. переполнения}

if (abs(s1)+abs(s2))>=10 then {если сумма абс. значений

цифр двух чисел >=10, то}

begin

s3:=abs(s1)+abs(s2)-10; {от нее отнимем 10 и}

d:=1; {переменная переполнения равна 1}

end

else if (abs(s1)+abs(s2))<10 then {если сумма абс. значений

цифр 2-х чисел <10, то}

begin

s3:=abs(s1)+abs(s2); {суммируем 2 выбр. цифры}

d:=0; {и перем. переполн. обнулим}

end;

str(s3,sk3); {результирующую цифру переведем в тип <строчное>}

rez:=sk3+rez; {и добавим ее спереди строки результата}

if ks1>0 then {если число a2 не пройдено до конца, то}

ks1:=ks1-1; {перейдем к более старшей цифре}

if ks2>0 then {если число b2 не пройдено до конца, то}

ks2:=ks2-1; {перейдем к более старшей цифре}

end; {цикл while}

if d<>0 then begin {если переменная переполнения <>0, то}

rez:= '1'+rez; {добавим спереди строки результата '1'}

d:=0; {обнулим переменную переполнения}

end;

end {if then}

else begin {иначе, если a2 и b2 неравнозначны}

if Bol(b2,a2)=1 {сравним выч. числа}

then begin fl:=true; {знак меняем на противоположный от a2}

bb1:=b2; {переприсваиваем}

bb2:=a2; {переприсваиваем}

end

else begin fl:=false;

bb1:=a2;

bb2:=b2;

end;

ks1:=length(bb1);

ks2:=length(bb2);

d:=0;

while not((ks1=0)and(ks2=0)) do

begin

s1:=0;

s2:=0;

s3:=0;

sk1:=copy(bb1,ks1,1);

if ks1>0

then if sk1<>'-' then val(sk1,s1,cd);

sk2:=copy(bb2,ks2,1);

if ks2>0

then if sk2<>'-' then val(sk2,s2,cd);

s2:=abs(s2)+d;

if (abs(s1)-abs(s2))<0

then begin s3:=abs(s1)+10-abs(s2);

d:=1;

end

else begin s3:=abs(s1)-abs(s2);

d:=0;

end;

str(s3,sk3);

rez:=sk3+rez;

if ks1>0 then ks1:=ks1-1;

if ks2>0 then ks2:=ks2-1;

end; {while}

end; {if else}

if (pos('-',a2)=0)and(fl) then rez:='-'+rez;

Deln(rez);

Sum:=rez;

end;

function TMainForm.Mins(a5,b5:string):string; {разность a5-b5}

var

m:boolean; {наличие минуса}

begin

if pos('-',b5)<>0 then begin

delete(b5,pos('-',b5),1);

m:=true;

end

else begin

b5:='-'+b5;

m:=false;

end;

mins:=sum(a5,b5);

if m then b5:='-'+b5

else delete(b5,pos('-',b5),1);

end;

function TMainForm.Umn(a4,b4:string):string; {целочисленное умножение}

var

s1,s2,s3,i,j:integer;

cd,ks1,ks2:integer;

sk1,sk2,sk3:string[1];

fl:boolean;

rez,bfr:string;

d:integer;

begin

ks1:=length(a4);

ks2:=length(b4);

bfr:='0';

while not(ks2=0) do

begin

d:=0;

s2:=0;

s3:=0;

rez:='';

ks1:=length(a4);

sk2:=copy(b4,ks2,1);

if ks2>0 then

if sk2<>'-' then val(sk2,s2,cd);

s2:=abs(s2);

while not(ks1=0) do

begin

s1:=0;

sk1:=copy(a4,ks1,1);

if ks1>0 then

if sk1<>'-' then val(sk1,s1,cd);

if (abs(s1)*abs(s2)+d)>=10 then

begin

s3:=(abs(s1)*abs(s2)+d)-((abs(s1)*abs(s2)+d)div 10)*10;

d:=(abs(s1)*abs(s2)+d)div 10;

end

else

if (abs(s1)*abs(s2)+d)<10 then

begin

s3:=abs(s1)*abs(s2)+d;

d:=0;

end;

str(s3,sk3);

rez:=sk3+rez;

if ks1>0 then ks1:=ks1-1;

end; {while}

if d<>0 then

begin

str(d,sk3);

rez:=sk3+rez;

d:=0;

end;

for j:=1 to length(b4)-ks2 do

rez:=rez+'0';

bfr:=sum(bfr,rez);

if ks2>0 then ks2:=ks2-1;

end; {while}

if ((pos('-',a4)<>0)and(pos('-',b4)=0))or {выставим знаки}

((pos('-',a4)=0)and(pos('-',b4)<>0))

then bfr:='-'+bfr;

deln(bfr);

umn:=bfr;

end;

function TMainForm.Divis(a6,b6:string):string; {целочисленное деление a6 div b6}

var

bfr,bfr1,bfr2,rez:string;

kp1:string;

kp2:string[1];

kp,ig,cd:integer;

begin

if bol(b6,'0')<>0 then

begin

bfr:='0';

rez:='0';

for kp:=1 to length(a6) do

begin

bfr:=bfr+copy(a6,kp,1);

kp1:='0';

while bol(bfr,b6)<>2 do

begin

bfr:=mins(bfr,b6);

kp1:=sum(kp1,'1');

end;

val(kp1,ig,cd);

str(ig,kp2);

if (bol(rez,'0')<>0)and(bol(bfr,b6)=2)

and(bol(kp1,'0')=0)

then rez:=rez+'0'

else if bol(kp1,'0')<>0

then rez:=rez+kp2;

end; {for}

deln(rez);

if ((pos('-',a6)<>0)and(pos('+',b6)=0))or

((pos('+',a6)=0)and(pos('-',b6)<>0))

then rez:='-'+rez;

divis:=rez;

end; {if then}

end;

function TMainForm.Modulo(a7,b7:string):string; {взятие от a7 остатка

по модулю b7}

var

modulo1:string;

begin

modulo1:='';

modulo1:=mins(a7,umn(divis(a7,b7),b7));

deln(modulo1);

modulo:=modulo1;

end;

procedure TMainForm.Hamcode; {вычисление кода Хэмминга}

var

ih,jh:integer;

c:integer;

begin

for ih:=hc downto 0 do

begin

hamming[ih]:=false;

for jh:=ic downto 0 do

hamming[ih]:=hamming[ih] xor(prmx[jh,ih]and coderc[jh]);

end;

end;

procedure TMainForm.Dhamm; {восстановление ошибок по коду Хэмминга}

var

i1,j1,c,kn,a,b,d:integer;

ve:array[0..wl] of boolean; {вектор ошибок}

se:array[0..hc] of boolean; {синдром}

gh:boolean;

begin

for i1:=hc downto 0 do

begin

se[i1]:=false;

for j1:=wl downto 0 do

se[i1]:=se[i1] xor(incode[j1]and prmx1[i1,j1]);

end;

for i1:=wl downto 0 do

begin

c:=0;

for j1:=hc downto 0 do

if se[j1]=prmx1[j1,i1] then c:=c+1;

if c=hc+1

then ve[i1]:=true

else ve[i1]:=false;

end;

kn:=0;

for i1:=wl downto 0 do

if ve[i1] then wer:=wer+1;

km:=km+1;

for i1:=wl downto 0 do

if ve[i1] then

if wer=1 then

incode[i1]:=incode[i1]xor ve[i1];

end;

function TMainForm.Recod:string; {перевод двоичного кода в десятичное число}

var

l1:integer;

recod1:string;

begin

recod1:='0';

for l1:=wl downto hc+1 do

if incode[l1] then

recod1:=sum(recod1,b[l1-ic]);

recod:=recod1;

end;

function TMainForm.Der1(a11,b11,c11:string):string; {вычисление a11 в степени

b11 по модулю c11}

var

bfs,buf,buf1:string;

b17,b13,b12,b14,kt:string;

s12:string;

sd,bd:integer;

begin

bfs:=b11;

bd:=76;

while bol(bfs,b[bd])=2 do

bd:=bd-1;

bfs:=mins(bfs,b[bd]);

buf:=a11;

bd:=bd-1;

while bd>=0 do

begin

if bol(bfs,b[bd])=2

then buf:=modulo(umn(buf,buf),c11)

else begin

buf:=modulo(umn(buf,buf),c11);

buf:=modulo(umn(a11,buf),c11);

bfs:=mins(bfs,b[bd]);

end;

delete(buf,1,length(buf)-length(c11));

bd:=bd-1;

end;

der1:=buf;

end;

procedure TMainForm.GenKeys; {генерация ключей}

var

ci,cj:integer; {счетчики циклов}

bc:longint; {переменная для генерации большого случайного числа}

randt1:longint; {число генераций}

p,ksy:integer; {счетчики циклов}

prov:string; {основание теста Ферма}

flag:boolean; {вспомогательные переменные}

P1,Q1,E1,D1:string; {ключевые числа}

qs,qm,an,bn,buf:string; {вспомогательные переменные}

am:array[0..1]of string; {вспомогат. переменные для алгоритма Евклида}

begin

WaitForm.Timer1.Enabled:=true;

try

AssignFile(Sekret,'SekrKey');

AssignFile(UnSekret,'UnSKey');

skbin[0]:=true;

{генерация P1}

bc:=0;

for ci:=1 to skd do

begin

randt1:=random(5000);

WaitForm.SetFocus;

for cj:=0 to randt1 do

begin

Application.ProcessMessages;

bc:=random(65535);

end;

if (bc mod 2)=0 then bc:=0

else bc:=1;

if bc=1 then skbin[ci]:=true

else skbin[ci]:=false;

end; {for ci}

P1:='0';

for cj:=0 to skd do {преобразуем в десятичный вид}

if skbin[cj] then P1:=sum(P1,b[cj]);

if P1[length(P1)]='5'

then P1:=sum(P1,'2');

prov:=''; {проверка на простоту}

prov:=der1('8',mins(P1,'1'),P1);

prov:=mins(prov,'1');

repeat

flag:=true;

while bol(modulo(prov,P1),'0')<>0 do

begin

if P1[length(P1)]='3'

then P1:=sum(P1,'4')

else P1:=sum(P1,'2');

prov:=der1('8',mins(P1,'1'),P1);

prov:=mins(prov,'1');

end; {while}

if not ftest then

begin

qs:='3';

while (bol(modulo(P1,qs),'0')<>0)and

(bol(umn(qs,qs),P1)=2) do

if qs[length(qs)]='3'

then qs:=sum(qs,'4')

else qs:=sum(qs,'2');

if (bol(umn(qs,qs),P1)=0)or

(bol(modulo(P1,qs),'0')=0)

then begin

if P1[length(P1)]='3'

then P1:=sum(P1,'4')

else P1:=sum(P1,'2');

flag:=false;

end;

end; {if}

until flag;

{генерация Q1}

bc:=0;

for ci:=1 to skd do

begin

randt1:=random(5000);

WaitForm.SetFocus;

for cj:=0 to randt1 do

begin

Application.ProcessMessages;

bc:=random(65535);

end;

if (bc mod 2)=0 then bc:=0

else bc:=1;

if bc=1 then skbin[ci]:=true

else skbin[ci]:=false;

end; {for ci}

Q1:='0';

for cj:=0 to skd do {преобразуем в десятичный вид}

if skbin[cj] then Q1:=sum(Q1,b[cj]);

if Q1[length(Q1)]='5'

then Q1:=sum(Q1,'2');

prov:='';

prov:=der1('8',mins(Q1,'1'),Q1);

prov:=mins(prov,'1');

repeat

flag:=true;

while bol(modulo(prov,Q1),'0')<>0 do

begin

if P1[length(Q1)]='3'

then Q1:=sum(Q1,'4')

else Q1:=sum(Q1,'2');

prov:=der1('8',mins(Q1,'1'),Q1);

prov:=mins(prov,'1');

end; {while}

if not ftest then

begin

qs:='3';

while (bol(modulo(Q1,qs),'0')<>0)and

(bol(umn(qs,qs),Q1)=2) do

if qs[length(qs)]='3'

then qs:=sum(qs,'4')

else qs:=sum(qs,'2');

if (bol(umn(qs,qs),Q1)=0)or

(bol(modulo(Q1,qs),'0')=0)

then begin

if Q1[length(Q1)]='3'

then Q1:=sum(Q1,'4')

else Q1:=sum(Q1,'2');

flag:=false;

end;

end; {if}

until flag;

{генерация E1}

skbin[0]:=true;

bc:=0;

for ci:=1 to skd do

begin

randt1:=random(5000);

for cj:=0 to randt1 do

bc:=random(65535);

if (bc mod 2)=0 then bc:=0

else bc:=1;

if bc=1 then skbin[ci]:=true

else skbin[ci]:=false;

end;

E1:='0';

for cj:=0 to skd do

if skbin[cj]

then E1:=sum(E1,b[cj]);

eyl:=umn(mins(P1,'1'),mins(Q1,'1'));

qs:='0';

am[0]:='0';

am[1]:='1';

repeat

am[0]:=E1;

am[1]:=eyl;

while bol(am[1],'0')<>0 do

begin

qs:=divis(am[0],am[1]);

buf:=am[0];

delete(am[0],1,length(am[0])-length(eyl)-1);

delete(am[1],1,length(am[1])-length(eyl)-1);

am[0]:=am[1];

am[1]:=mins(buf,umn(am[1],qs));

end;

if bol(am[0],'1')<>0

then begin

E1:=sum(E1,'2');

am[0]:=E1;

end;

until bol(am[0],'1')=0;

{генерация D1}

an:='1';

bn:='1';

qm:=eyl;

qs:='2';

while bol(qm,'1')<>0 do

begin

if bol(modulo(qm,qs),'0')=0 then

begin

while bol(modulo(qm,qs),'0')=0 do

qm:=divis(qm,qs);

an:=umn(mins(qs,'1'),an);

bn:=umn(qs,bn);

end;

if bol(modulo(qs[length(qs)],'2'),'0')=0

then qs:=sum(qs,'1')

else qs:=sum(qs,'2');

if bol(umn(qs,qs),qm)<>2

then qs:=qm;

end; {while}

D1:=der1(E1,mins(divis(umn(eyl,an),bn),'1'),eyl);

security.P:=P1;

security.Q:=Q1;

security.D:=D1;

dkeys.N:=umn(P1,Q1);

dkeys.E:=E1;

{Запись ключей в файл}

Reset(UnSekret);

seek(UnSekret,Filesize(UnSekret));

BlockWrite(UnSekret,dkeys,SizeOf(dkeys));

CloseFile(UnSekret);

Reset(Sekret);

seek(Sekret,Filesize(Sekret));

BlockWrite(Sekret,security,SizeOf(security));

CloseFile(Sekret);

{переменная сигнализирует о том, что генерация состоялась}

KeyFlag:=true;

if KeyFlag then

MainForm.Cipher1.Enabled:=true;

MainForm.Decipher1.Enabled:=true;

MainForm.Open1.Enabled:=true;

except

on EFOpenError do ShowMessage('файл ключей не найден');

on EInOutError do ShowMessage('нельзя записывать в этот файл');

end;

WaitForm.Timer1.Enabled:=false;

end;

{$R *.DFM}

procedure TMainForm.Open1Click(Sender: TObject);

begin

if OpenDialog1.Execute then

begin

Caption:='RSA--'+OpenDialog1.FileName;

MainForm.Open1.Enabled:=false;

MainForm.Close1.Enabled:=true;

Memo1.Clear;

Memo1.Lines.LoadFromFile(OpenDialog1.FileName);

end;

if KeyFlag then

begin

CipherForm.Enabled:=true;

DecipherForm.Enabled:=true;

end;

Open1.Enabled:=false;

end;

procedure TMainForm.Close1Click(Sender: TObject);

begin

Close;

end;

procedure TMainForm.Save1Click(Sender: TObject);

begin

if OpenDialog1.FileName<>''

then Memo1.Lines.SaveToFile(SaveDialog1.FileName)

else Saveas1Click(Sender);

if KeyFlag and (not CipFlag) then CipherForm.Enabled:=true;

Open1.Enabled:=false;

Close1.Enabled:=true;

end;

procedure TMainForm.Saveas1Click(Sender: TObject);

begin

if Memo1.Lines.Count<>0

then with SaveDialog1 do

if Execute then begin

Memo1.Lines.SaveToFile(FileName);

Caption:='RSA--'+ExtractFileName(FileName);

end;

Save1.Enabled:=true;

if KeyFlag and (not CipFlag) then CipherForm.Enabled:=true;

Open1.Enabled:=false;

Close1.Enabled:=true;

end;

procedure TMainForm.About1Click(Sender: TObject);

var about:TAboutBox;

begin

about:=TAboutBox.Create(Self);

try about.ShowModal;

finally about.Free;

end;

end;

procedure TMainForm.AntiRSA1Click(Sender: TObject);

begin

AntiR.ShowModal;

end;

procedure TMainForm.KeysGeneration1Click(Sender: TObject);

var

i:integer;

begin {заполнение массива двоичных кодов}

b[0]:='1';

for i:=1 to IC do

b[i]:=umn(b[i-1],'2');

ChooseForm.ShowModal;

end;

procedure TMainForm.FromFile1Click(Sender: TObject);

begin {ключи для генерации извлекаются из файла}

try

AssignFile(Sekret,'SekrKey');

Reset(Sekret);

AssignFile(UnSekret,'dkeys');

Reset(UnSekret);

while not eof(Sekret) do

BlockRead(Sekret,security,SizeOf(sekret));

while not eof(UnSekret) do

BlockRead(UnSekret,dkeys,SizeOf(dkeys));

CloseFile(Sekret);

CloseFile(UnSekret);

CipherForm.Enabled:=true;

DecipherForm.Enabled:=true;

KeyFlag:=true;

except

on EFOpenError do ShowMessage('файл ключей не найден');

end;

end;

procedure TMainForm.Cipher1Click(Sender: TObject);

var

i,j:integer;

kodblock:string; {шифрблок}

key:string; {несекретный ключ N}

e:string; {несекретный ключ Е}

begin

AssignFile(UnSekret,'dkeys');

Reset(UnSekret);

while not eof(UnSekret) do

BlockRead(UnSekret,dkeys,SizeOf(dkeys));

key:=dkeys.N;

e:=dkeys.E;

CloseFile(UnSekret);

try

AssignFile(f1,OpenDialog1.FileName);

Rewrite(f1);

AssignFile(f2,'cipher');

Rewrite(f2);

CipherForm.Show;

Enabled:=false;

HelpForm.Enabled:=false;

for i:=0 to Memo1.Lines.Count-1 do

begin

for j:=1 to Length(Memo1.Lines[i]) do

write(f1,Memo1.Lines[i][j]);

ch:=chr(13);

write(f1,ch);

end;

CloseFile(f1);

Reset(f1);

CipherForm.Gauge1.MaxValue:=FileSize(f1)+1;

CipherForm.Gauge1.Progress:=0;

{------------------Шифрация----------------}

CipherForm.Gauge1.Progress:=CipherForm.Gauge1.Progress+1;

while not eof(f1) do

begin

read(f1,ch);

temp:=ord(ch);

str(temp,tc1);

kodblock:=der1(tc1,e,key);

write(f2,kodblock);

Hamcode; {добавление кодов Хэмминга}

for i:=HC downto 0 do

write(f2,Hamming[i]);

CipherForm.Gauge1.Progress:=CipherForm.Gauge1.Progress+1;

Application.ProcessMessages;

end;

CloseFile(f1);

CloseFile(f2);

Reset(f2);

tc1:='0';

Memo1.Clear;

Memo1.Lines.LoadFromFile('cipher');

CloseFile(f2);

CipherForm.Close;

Enabled:=true;

CipherForm.Enabled:=false;

DecipherForm.Enabled:=true;

except

on EFOpenError do ShowMessage('файл ключей не найден');

on EInOutError do ShowMessage ('нельзя записывать в этот файл');

end;

cipflag:=true;

end;

procedure TMainForm.Decipher1Click(Sender: TObject);

var

set1:set of '0'..'9';

i,j:integer;

sim,sim1,cdb:string; {переменная для преобразования символов}

key,key1,key2,dm,kodblock:string; {ключи}

asc,cd:integer; {переменные для ASCII-кодов}

fileflag:boolean;

begin

AssignFile(Sekret,'SekrKey');

Reset(Sekret);

while not eof(Sekret) do

BlockRead(Sekret,security,SizeOf(sekret));

key1:=security.P;

key2:=security.Q;

dm:=security.D;

eyl:=umn(mins(key1,'1'),mins(key2,'1'));

CloseFile(Sekret);

fileflag:=true;

set1:=['0','1','2','3','4','5','6','7','8','9'];

try

AssignFile(f2,'cipher');

Rewrite(f2);

for i:=0 to Memo1.Lines.Count-1 do

begin

writeln(f2,Memo1.Lines[i]);

end;

CloseFile(f2);

Reset(f2);

if Memo1.Lines[0][1] in set1 {проверка шифра}

then fileflag:=true

else fileflag:=false;

if fileflag then

begin

AssignFile(f3,'decipher');

Rewrite(f3);

DecipherForm.Show;

Enabled:=False;

HelpForm.Enabled:=false;

DecipherForm.Gauge1.MaxValue:=CipherForm.Gauge1.MaxValue;

DecipherForm.Gauge1.Progress:=0;

{---------------------Дешифрация-------------------}

Application.ProcessMessages;

DecipherForm.Gauge1.Progress:=DecipherForm.Gauge1.Progress+1;

j:=0;

i:=WL;

while not eof(f2) do

begin

seek(f2,j);

BlockRead(f2,incode[i]);

if j>0 then

if i=0 then

begin

cp:=cp+1;

i:=WL+1;

Dhamm; {корректировка блоков по кодам Хэмминга}

sim:='';

sim:=der1(cdb,dm,umn(key1,key2));

Reset(f3);

while length(sim)>0 do

begin

if (length(sim) mod 3)<>0

then begin

sim1:=copy(sim,1,length(sim) mod 3);

val(sim1,asc,cd);

delete(sim,1,length(sim) mod 3);

end

else begin

sim1:=copy(sim,1,3);

val(sim1,asc,cd);

delete(sim,1,3);

end;

if asc>0 then

begin

seek(f3,filesize(f3));

ch:=chr(asc-1);

write(f3,ch);

end;

end; {while}

end; {if}

i:=i-1;

j:=j+1;

Application.ProcessMessages;

DecipherForm.Gauge1.Progress:=DecipherForm.Gauge1.Progress+1;

end; {while not eof(f2)}

CloseFile(f2);

CloseFile(f3);

DecipherForm.Close;

Enabled:=true;

MainForm.Decipher1.Enabled:=false;

MainForm.Cipher1.Enabled:=true;

Memo1.Clear;

Memo1.Lines.LoadFromFile('decipher');

Erase(f3);

end {then}

else begin

ShowMessage('этот файл не является шифром');

DecipherForm.Enabled:=false;

CloseFile(f2);

end;

except

on EFOpenError do ShowMessage('файл ключей не найден');

on EInOutError do ShowMessage('нельзя записывать в этот файл');

end;

cipflag:=true;

end;

procedure TMainForm.Help2Click(Sender: TObject);

begin

HelpForm.Enabled:=true;

HelpForm.ShowModal;

end;

procedure TMainForm.Close2Click(Sender: TObject);

begin

if CipFlag then

begin

Saveas1Click(Sender);

CipFlag:=false;

end;

Caption:='RSA';

MainForm.Open1.Enabled:=true;

Memo1.Clear;

end;

procedure TMainForm.FormActivate(Sender: TObject);

begin

KeyFlag:=false;

CipFlag:=false;

end;

end.

Приложение 2

Текст модуля выбора теста простоты

unit Choose;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls;

type

TChooseForm = class(TForm)

RadioGroup1: TRadioGroup;

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

ChooseForm: TChooseForm;

implementation

uses MainProg, Wait;

{$R *.DFM}

procedure TChooseForm.Button1Click(Sender: TObject);

begin

ftest:=ChooseForm.RadioGroup1.ItemIndex=0;


Подобные документы

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

    курсовая работа [3,3 M], добавлен 11.03.2013

  • Традиционные симметричные криптосистемы. Основные понятия и определения. Методы шифрования. Метод перестановок на основе маршрутов Гамильтона. Асимметричная криптосистема RSA. Расширенный алгоритм Евклида. Алгоритмы электронной цифровой подписи Гамаля.

    курсовая работа [235,6 K], добавлен 06.01.2017

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

    дипломная работа [1,6 M], добавлен 17.07.2016

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

    дипломная работа [802,2 K], добавлен 08.06.2013

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

    дипломная работа [968,8 K], добавлен 01.07.2011

  • Автоматизация процесса шифрования на базе современных информационных технологий. Криптографические средства защиты. Управление криптографическими ключами. Сравнение симметричных и асимметричных алгоритмов шифрования. Программы шифрования информации.

    курсовая работа [795,7 K], добавлен 02.12.2014

  • Сравнительный анализ роторной криптосистемы на основании криптографической машины "Энигма" времен второй мировой войны и усовершенствованной "Энигма". Ассиметричная система шифрования и дешифрования данных RSA, ее принципиальное отличие от симметричных.

    курсовая работа [1,7 M], добавлен 14.12.2012

  • Статистический анализ текстов, созданных программой симметричного шифрования. Реализация симметричного криптоалгоритма. Основные шаги в использовании криптосистемы PGP. Генерация ключей, шифрование и расшифровка сообщений. Защита от сетевых атак.

    лабораторная работа [1,7 M], добавлен 06.07.2009

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

    курсовая работа [129,6 K], добавлен 17.02.2011

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

    лабораторная работа [326,0 K], добавлен 04.11.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.