Программная система 'Обеспечение безопасности электронного документооборота'

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    326,37 Кб
  • Опубликовано:
    2015-01-27
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Программная система 'Обеспечение безопасности электронного документооборота'

Министерство образования и науки Российской Федерации

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

"Оренбургский государственный университет"

Факультет информационных технологий

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

ОГУ 230105.65.4014.062 О





Курсовой проект

Программная система "Обеспечение безопасности электронного документооборота"


Руководитель

Цыганков А.С.

Исполнитель

студент группы з-10ПОВТ(у)

Майборода З.П.


Оренбург 2014

Содержание

Введение

. Постановка задачи

. Теоретические предпосылки

2.1 Алгоритм RSA

2.1 Ассиметричные алгоритмы

. Руководство пользователя

Заключение

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

Приложение А

Введение

Целью данной курсовой работы являлось написание программной системы, формирующей виртуальные защищенные каналы передачи данных, на языке программирования C# при помощи программного средства Visual Studio 2010. Написание программной системы осуществлялось с использованием классов т.д.

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

1. Постановка задачи

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

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

.        Генерация ключей для метода RSA, с сохранением в файл.

Размер ключа 32 бита (p и q, integer p и q берем длиной 32 бита).

         Верхний порог генерации - 232

         Нижний порог генерации - 231

         Число длиной 32 бита

         е - произвольно (3, 17…)

.        Шифрование файлов.

С помощью сгенерированных ранее ключей, с сохранением в файл (на форме показывать не надо, просто в новый файл).

.        Расшифрование с сохранением в файл.

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

. Теоретические предпосылки

 

.1 Алгоритм RSA


Алгоритм RSA стоит у истоков асимметричной криптографии. Он был предложен тремя исследователями-математиками Рональдом Ривестом (R. Rivest), Ади Шамиром (A. Shamir) и Леонардом Адльманом (L. Adleman) в 1977-78 годах.

Первым этапом любого асимметричного алгоритма является создание пары ключей: открытого и закрытого и распространение открытого ключа "по всему миру". Для алгоритма RSA этап создания ключей состоит из следующих операций:

1 Выбираются два простых (!) числа p и q.

2       Вычисляется их произведение n(=p*q).

         Выбирается произвольное число e (e<n), такое, что НОД(e, (p-1)(q-1))=1, то есть e должно быть взаимно простым с числом (p-1)(q-1).

         Методом Евклида решается в целых числах (!) уравнение e*d+(p-1)(q-1)*y=1. Здесь неизвестными являются переменные d и y - метод Евклида как раз и находит множество пар (d, y), каждая из которых является решением уравнения в целых числах.

         Два числа (e, n) - публикуются как открытый ключ.

         Число d хранится в строжайшем секрете - это и есть закрытый ключ, который позволит читать все послания, зашифрованные с помощью пары чисел (e, n).

Как же производится собственно шифрование с помощью этих чисел:

         Отправитель разбивает свое сообщение на блоки, равные k=[log2(n)] бит, где квадратные скобки обозначают взятие целой части от дробного числа.

         Подобный блок, как Вы знаете, может быть интерпретирован как число из диапазона (0; 2k-1). Для каждого такого числа (назовем его mi) вычисляется выражение ci=((mi)e)mod n. Блоки ci и есть зашифрованное сообщение Их можно спокойно передавать по открытому каналу, поскольку операция возведения в степень по модулю простого числа, является необратимой математической задачей. Обратная ей задача носит название "логарифмирование в конечном поле" и является на несколько порядков более сложной задачей. То есть даже если злоумышленник знает числа e и n, то по ci прочесть исходные сообщения mi он не может никак, кроме как полным перебором mi.

А вот на приемной стороне процесс дешифрования все же возможен, и поможет нам в этом хранимое в секрете число d. Достаточно давно была доказана теорема Эйлера, частный случай которой утверждает, что если число n представимо в виде двух простых чисел p и q, то для любого x имеет место равенство (x(p-1)(q-1))mod n =1. Для дешифрования RSA-сообщений воспользуемся этой формулой. Возведем обе ее части в степень (-y):

(x(-y)(p-1)(q-1))mod n =1(-y)=1.

Теперь умножим обе ее части на x:

(x(-y)(p-1)(q-1)+1)mod n =1*x=x.

А теперь вспомним как мы создавали открытый и закрытый ключи. Мы подбирали с помощью алгоритма Евклида d такое, что e*d+(p-1)(q-1)*y=1, то есть e*d=(-y)(p-1)(q-1)+1. А следовательно в последнем выражении предыдущего абзаца мы можем заменить показатель степени на число (e*d). Получаем (xe*d)mod n=x. То есть для того чтобы прочесть сообщение ci=((mi)e)mod n достаточно возвести его в степень d по модулю m:

((ci)d)mod n = ((mi)e*d)mod n = mi.

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

.2 Ассиметричные алгоритмы

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

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

Рисунок 1 - Схема ассиметричного шифрования

Идея асимметричных алгоритмов тесно связана с развитием теории односторонних функций и с теорией сложности. Под односторонней функцией мы будем понимать легковычисляемое отображение f(x): XÎ Y, x ®X, при этом обратное отображение является сложной задачей. Она называется трудновычисляемой, если нет алгоритма для ее решения с полиномиальным временем работы. Легковычисляемой будем называть задачу, имеющую алгоритм со временем работы, представленным в виде полинома низкой степени относительно входного размера задачи, а еще лучше алгоритм с линейным временем работы.

Развитием идеи односторонних функций явилось построение односторонних функций с секретом (с потайным ходом). Такой функцией называется f(x) = y8, значение которой, как и в предыдущем случае, легко вычислить, тогда как обратное значение без знания некоторого секрета трудно вычислить. Знание же секрета позволяет достаточно просто реализовывать операцию обращения односторонних функций с секретом. На практике при применении асимметричного алгоритма шифрования в роле секретного ключа выступает само знание секрета, а в роле открытого ключа - знание процедуры вычисления односторонней функции с секретом.

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

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

·              факторизация больших чисел.

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

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

Для любого неотрицательного числа X и любого положительного числа Y справедливо следующее:

gcd (X, Y) = gcd (Y, X mod Y),

где X>Y>0.

Чтобы определить наибольший общий делитель, приведенное выше равенство (1) необходимо использовать многократно (до получения значения Y = 0). Ниже приводится раскрытая запись

(X, Y) = gcd (Y, X mod Y) = gcd (Y, X - (лX/Yы - целое частное) ґ Y)).

. Руководство пользователя

Для запуска серверного приложения программы необходимо запустить файл "RSA.exe".

В появившемся окне можно выполнить следующие действия:

·        Сгенерировать числа

·        Сохранить и загрузить из файла

·        Зашифровать

·        Расшифровать

Рисунок 2 - Главное окно

Для генерации числа нужно нажать "Генерировать". Произойдет генерация ключей методом RSA с сохранением в файл.

При нажатие на кнопку "Зашифровать" и "Расшифровать" появляется окно, где нужно открыть файл ранее сгенерированный и сохраненный.

Рисунок 3 - Шифрование файла

Заключение

В ходе проделанной курсовой работы была написана программная система, формирующая виртуальные защищенные каналы передачи данных, на языке программирования C# при помощи программного средства Visual Studio 2010. Написание программной системы осуществлялось с использованием классов т.д.

Во время выполнения расчетно-графического задания было осуществлено закрепление и повтор теоретических и практических знаний, полученных на занятиях, при изучении дисциплины "Методы и средства защиты информации".

Список используемых источников

1. Троелсен Э. С# и платформа .NET. Библиотека программиста. - СПб.: Питер, 2004. - 796 с.: ил.

. Фаронов В.В. Программирование на языке C# - СПб.: Питер, 2007. - 240 с.: ил.

3. Селентьева И.В. Программирование на языке высокого уровня, С# 2001 г. - 460 с.

4. Вильямс Книга C# 3.0: руководство для начинающих Герберта Шилдта 2005 г. - 330 с.

5. СТО 02069024.101-2010. Стандарт организации. Работы студенческие. Общие требования и правила оформления. Режим доступа: http://www.osu.ru/doc/381

. Орлов С.А. Технология разработки программного обеспечения. - Спб.: Питер, 2002 - 464 с.

. Пауэрс Л. Microsoft Visual Studio 2010 / Л. Пауэрс, М. Снелл: Пер. с англ. - СПб.: БХВ-Петербург, 2010. - 1200 с.: ил.

. Либерти, Д.: Программирование на C#.-Пер. с англ..- СПб:Символ-Плюс, 2003.- 688с.

. Петцольд Ч. Программирование для Microsoft Windows на C#. В 2-х томах, Том 1-2. - Пер. с англ. - М: Издательско-торговый дом "Русская редакция", 2002

. Марченко А.Л. Основы программирования на C# 2.0 - М.: "Интернет-университет информационных технологий - ИНТУИТ.ру”, "БИНОМ. Лаборатория знаний” - 2007 г. - 552 стр.

Приложение А

(обязательное)

Текст программы

Unit1.cpp

#include <vcl.h>

#include <math.h>

#include <stdio.h>

#include <io.h>

#include <time.h>

#pragma hdrstop

#include "Unit1.h"

#include "RSAutil.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"*Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{(time(NULL)); // Инициализация генератора случайных чисел

}

//---------------------------------------------------------------------------__fastcall TForm1::ButtonGenerateClick(TObject *Sender)

{pubKey;privKey;(&pubKey, &privKey);>Text = IntToStr(pubKey.e);>Text = IntToStr(pubKey.n);>Text = IntToStr(privKey.d);->Text = IntToStr(privKey.n);>Enabled = true;>Enabled = true;->SimpleText = "Ключи RSA сгенерированы";

}

//---------------------------------------------------------------------------__fastcall TForm1::btnPublicSaveClick(TObject *Sender)

{( !SaveDialogPublicKeys->Execute() ) return;fname = SaveDialogPublicKeys->FileName;( fname.SubString(fname.Length()-3, 4).LowerCase() != ".pbk" )+= ".pbk";*f = fopen(fname.c_str(), "wb");( !f ) { // Файл не открылся->SimpleText = "Ошибка открытия файла "+fname;;

}e = atol(EditE->Text.c_str());n = _atoi64(EditN->Text.c_str());(&e, sizeof(Int32), 1, f);(&n, sizeof(Int64), 1, f);(f);->SimpleText = "Открытый ключ записан в файл "+fname;

}

//---------------------------------------------------------------------------__fastcall TForm1::btnPublicLoadClick(TObject *Sender)

{( !OpenDialogPublicKeys->Execute() ) return;*f = fopen((OpenDialogPublicKeys->FileName).c_str(), "rb");( !f ) { // Файл не открылся->SimpleText = "Ошибка открытия файла "+ OpenDialogPublicKeys->FileName;;

}e;n;(&e, sizeof(Int32), 1, f);(&n, sizeof(Int64), 1, f);(f);>Text = IntToStr(e);>Text = IntToStr(n);->SimpleText = "Открытый ключ загружен";

}

//---------------------------------------------------------------------------__fastcall TForm1::btnPrivateSaveClick(TObject *Sender)

{( !SaveDialogPrivateKeys->Execute() ) return;fname = SaveDialogPrivateKeys->FileName;( fname.SubString(fname.Length()-3, 4).LowerCase() != ".prk" )+= ".prk";*f = fopen(fname.c_str(), "wb");( !f ) { // Файл не открылся->SimpleText = "Ошибка открытия файла "+fname;;

}d = _atoi64(EditD->Text.c_str());n = _atoi64(EditN2->Text.c_str());(&d, sizeof(Int64), 1, f);(&n, sizeof(Int64), 1, f);(f);->SimpleText = "Закрытый ключ записан в файл "+fname;

}

//---------------------------------------------------------------------------__fastcall TForm1::btnPrivateLoadClick(TObject *Sender)

{( !OpenDialogPrivateKeys->Execute() ) return;*f = fopen((OpenDialogPrivateKeys->FileName).c_str(), "rb");( !f ) { // Файл не открылся->SimpleText = "Ошибка открытия файла "+ OpenDialogPrivateKeys->FileName;;

}d;n;(&d, sizeof(Int64), 1, f);(&n, sizeof(Int64), 1, f);(f);>Text = IntToStr(d);->Text = IntToStr(n);->SimpleText = "Закрытый ключ загружен";

//---------------------------------------------------------------------------__fastcall TForm1::btnEncryptClick(TObject *Sender)

{( EditE->Text.IsEmpty() ) {->SimpleText = "Не задана открытая экспонента e";;

}( EditN->Text.IsEmpty() ) {->SimpleText = "Не задан модуль n";;

}pubKey;.e = atol(EditE->Text.c_str());.n = _atoi64(EditN->Text.c_str());( !OpenDialogEncrypt->Execute() ) return;*f = fopen(OpenDialogEncrypt->FileName.c_str(), "rb");( !f ) { // Файл не открылся->SimpleText = "Ошибка открытия файла "+ OpenDialogEncrypt->FileName;;

}*g = fopen((OpenDialogEncrypt->FileName+".enc").c_str(), "wb");( !g ) { // Файл не открылся->SimpleText = "Ошибка создания файла "+ OpenDialogEncrypt->FileName+".enc";(f);;

}m; // Считанное сообщениеme; // Зашифрованное сообщениеr; // Счетчик считанных битов>Max = filelength(fileno(f))/sizeof(Int32);>Position = 0;(!feof(f)) {= fread(&m, 1, sizeof(Int32), f);( r < sizeof(Int32) ) { // Последние байты, которых меньше 4, пишем без шифрации(&m, 1, r, g);;

}= rsaEncrypt(m, &pubKey);(&me, 1, r, g);>StepIt();

}(f);(g);>Position = 0;->SimpleText = "Файл "+ OpenDialogEncrypt->FileName+" зашифрован";

}

//---------------------------------------------------------------------------__fastcall TForm1::btnDecryptClick(TObject *Sender)

{( EditD->Text.IsEmpty() ) {->SimpleText = "Не задана секретная экспонента d";;

}( EditN2->Text.IsEmpty() ) {->SimpleText = "Не задан модуль n";;

}privKey;.d = _atoi64(EditD->Text.c_str());.n = _atoi64(EditN2->Text.c_str());( !OpenDialogDecrypt->Execute() ) return;fname = OpenDialogDecrypt->FileName;( fname.SubString(fname.Length()-3, 4).LowerCase() == ".enc" )= fname.SubString(0, fname.Length()-4);>FileName = fname;( !SaveDialogDecrypt->Execute() ) return;*f = fopen(OpenDialogDecrypt->FileName.c_str(), "rb");( !f ) { // Файл не открылся->SimpleText = "Ошибка открытия файла "+ OpenDialogDecrypt->FileName;;

}*g = fopen(SaveDialogDecrypt->FileName.c_str(), "wb");( !g ) { // Файл не открылся->SimpleText = "Ошибка создания файла "+ OpenDialogEncrypt->FileName+".enc";(f);;

}me; // Зашифрованное сообщениеm; // Расшифрованное сообщениеr; // Счетчик считанных битов>Max = filelength(fileno(f))/sizeof(Int32);>Position = 0;(!feof(f)) {= fread(&me, 1, sizeof(Int32), f);

if ( r < sizeof(Int32) ) { // Последние байты, которых меньше 4, пишем без расшифрования(&me, 1, r, g);;

}= rsaDecrypt(me, &privKey);(&m, 1, r, g);>StepIt();

}(f);(g);>Position = 0;->SimpleText = "Файл "+ OpenDialogDecrypt->FileName+" расшифрован";

}

//---------------------------------------------------------------------------

RSAutil.cpp

#pragma hdrstop

#include "RSAutil.h"

#include "Numeric.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

// Методы RSA

// Генерация ключейrsaGenerate(rsaPublicKey *pubKey, rsaPrivateKey *privKey) {p, q, e;n, f, d;= 3; // Выбираем отрытую экспоненту E{= RandomPrime(16); // Случайные факторы= RandomPrime(16); //= (Int64)p*q; // Модуль= (Int64)(p-1)*(q-1); // Функция Эйлера

// Проверяем, что E взаимно простое c f( IsSimple(e, f) ) break;

}(1);

// Вычисляем секретную экспоненту= Inverse(e, f);>e = e;>n = n;>d = d;>n = n;

}

// Шифрование сообщения на открытом ключеrsaEncrypt(Int32 m, rsaPublicKey *pubKey) {me;(m < pubKey->n) {= ModPow(m, pubKey->e, pubKey->n);( me < pubKey->n) return me;m;

}m; // Числа меньше модуля не шифруем

}

// Дешифрование сообщения на закрытом ключеrsaDecrypt(Int32 c, rsaPrivateKey *privKey) {(c < privKey->n)ModPow(c, privKey->d, privKey->n);c; // Числа меньше модуля не расшифровываем

}

RSA.cpp

#include <vcl.h>

#pragma hdrstop

//---------------------------------------------------------------------------("Unit1.cpp", Form1);

//---------------------------------------------------------------------------WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

{>Initialize();>Title = "Шифрование методом RSA";>CreateForm(__classid(TForm1), &Form1);>Run();

}(Exception &exception)

{>ShowException(&exception);

}(...)

{

{Exception("");

}(Exception &exception)

{>ShowException(&exception);

}

}0;

}.cpp

#pragma hdrstop

#include <math.h>

#include <limits.h>

#include <stdlib.h>

#include "Numeric.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

// Арифметические алгоритмы

// Расширенный алгоритм Евклида нахождения наибольшего общего делителя чисел A и BEGCD(Int64 a, Int64 b, Int64 *u) {v[3];t[3];q;i;

// В массив u заносится большее число[0] = (a > b ? a : b); u[1] = 1;    u[2] = 0;[0] = (a > b ? b : a); v[1] = 0;     v[2] = 1;( v[0] != 0 ) {= u[0] / v[0];[0] = u[0] % v[0];[1] = u[1] - q*v[1];[2] = u[2] - q*v[2];( i = 0; i < 3; i++ ) u[i] = v[i];( i = 0; i < 3; i++ ) v[i] = t[i];

}

// В результате в массиве v будут числа: НОД(a, b), x, y - значения такие, что a*x + b*y = НОД(a, b)

}

// НОДGCD(Int64 a, Int64 b) {v[3];(a, b, v);v[0];

}

// Проверка взаимной простоты двух чиселIsSimple(Int64 a, Int64 b) {v[3];(a, b, v);( v[0] == (Int64) 1 )true; // Числа взаимно простые, если НОД = 1false;

// Инверсия C по модулю PInverse(Int64 c, Int64 p) {v[3];(p, c, v);( v[2] < 0 )v[2] + p;v[2];

}

// Быстрое возведение A в степень X по модулю PModPow(Int64 a, Int64 x, Int64 p) {r, b, s;= 1;= a;= 1L; // Устанавливаем бит в 1-ю позицию( b < x ) {( x & b ) { // Если в текущей позиции стоит единица= (r * s) % p;

}= (s * s) % p;*= 2; // Двигаем бит на следующую позицию

}r;

}

// Степень двойкиInt64 pow2(int t) {x = 1;(x<<t);

}

// Таблица простых чисел решетом Эратосфена

#define MAXSIEVE 30000 // Размер решета*prime; // Таблица найденных чиселprimeLen = 0; // Длина таблицы

// ПросеиваниеSieve() {isPrime[MAXSIEVE];i, j;(i=0; i<MAXSIEVE; i++) isPrime[i] = true;[0] = isPrime[1] = false;( i = 2; (i*i) < MAXSIEVE; i++ )(isPrime[i])(int j=i*i; j<MAXSIEVE; j+=i )[j] = false;

// Переписываем( i = 2; i<MAXSIEVE;i++ )( isPrime[i] ) primeLen++;= (int *) calloc(primeLen, sizeof(Int32));= 0;( i = 2; i<MAXSIEVE;i++ ) {( isPrime[i] ) {[j++] = i;

}

}

}

// Случайное нечетное число длиной k битOddRandom(long k) {i;mask = 1, n;-;(i = 1; i <= k; i++)|= 1 << i;(k < 16)= rand();

else= (rand() << 16) | rand();|= 1 << k;&= mask;((n & 1) == 0) n++;n;

}

// Генерация простого числа размером 32 бита методом Маурера

// Взято из книги Handbook of Applied Cryptography. Часть 4. Алгоритм 4.62RandomPrime(int k) {( primeLen == 0 ) Sieve(); // Создаем таблицу простых чиселp, s;isPrime;( k <= 20 ) { // Поиск случайного простого тривиальным делением, если число k достаточно маленькое{= OddRandom(k);= sqrt(p);= true;( int i = 0; i < primeLen; i++ ) {( prime[i] > s ) break;( (p % prime[i]) == 0 ) {= false;;

};

}( isPrime );

} while (true);

}{ // Рекурсивное построениеc = 0.1, r;m = 20;B = c*k*k; // Граница тривиального деления

// Генерируем r - случайное число длиной от k/2 до k-m бит(k > 2 * m){= rand() / (double) RAND_MAX;= pow(2.0, s - 1.0);

} while (k - r * k <= m);= 0.5;

// Вычисляем простое меньшего размераq = RandomPrime(r * k + 1);I = floor(pow2(k-1)/(2.0*k));R, n, a, b, d;success = false;( !success ) {

// Выбираем кандидата в простые в интервале [I+1, 2I](true) {= random(I);( R < I) break;

}шифрование виртуальный алгоритм программа= R + I + 1;= 2*q*R + 1; // n - кандидат

// Проверка тривиальным делением по границе B( int i = 0; i < primeLen; i++ ) {( (n % prime[i]) == 0 );( prime[i] >= B ) {(true) {= random(n-4) + 2;( (a > 1) && (a < (n-1)) ) break;

}= ModPow(a, n-1, n);( b == 1 ) {= ModPow(a, 2*R, n);= GCD(b-1, n);( d == 1 ) {n;

}

};

}

};

}

}p;

}

Похожие работы на - Программная система 'Обеспечение безопасности электронного документооборота'

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!