2.3. Использование классов асимметричной криптографии

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

На рис. 4 приведено главное окно разрабатываемой программы.

Рис. 4. Окно программы вычисления и проверки ЭЦП для файла

В табл. 3 приведены имена объектов программы, которым соответствуют элементы управления главного окна.

Таблица 3

Имена объектов программ для элементов управления

Элемент управления окна

Его имя в программе

Редактор для ввода (выбора) имени защищенного файла

InputFName

Кнопка «Выбор файла»

Browse

Строка для отображения имени файла с ЭЦП

SigFName

Строка для отображения имени файла с открытым ключом

PubFName

Кнопка «Подписать»

Sign

Кнопка «Проверить ЭЦП»

Verify

Кнопка «Выход»

Exit

В программе используется класс File из пространства имен System. IO, содержащий статические методы для действий с файлами, и один из таких методов

bool Exists(string path) – проверка существования файла с полным именем path.

Ниже приведен текст программы:

using System;

using System. Collections. Generic;

using ponentModel;

using System. Data;

using System. Drawing;

using System. Linq;

using System. Text;

using System. Windows. Forms;

// подключение пространства имен криптографических классов

НЕ нашли? Не то? Что вы ищете?

using System. Security. Cryptography;

// подключение пространства имен классов ввода-вывода

using System. IO;

namespace WindowsFormsApplication3

{

public partial class Form1 : Form

{

// объект класса для криптоалгоритма DSA

DSACryptoServiceProvider dsa;

// блоб для открытого ключа ЭЦП

byte[] key;

// объекты для потоков защищенного файла, ЭЦП и открытого ключа

FileStream finStream, fsigStream, fpubStream;

// буфер для ЭЦП

byte[] sigbytes;

// буфер для ввода данных из защищенного файла

byte[] bytes;

// длина буфера ввода

int numBytesToRead;

// объект класса исключения

ArgumentException ex;

// объект для диалога открытия файла

OpenFileDialog openFileDialog1;

// конструктор класса главного окна

public Form1()

{

InitializeComponent();

// создание объекта для криптоалгоритма c длиной ключа 1024 бит

dsa = new DSACryptoServiceProvider(1024);

}

// обработка нажатия кнопки "Выход"

private void Exit_Click(object sender, EventArgs e)

{

// закрытие главного окна

Close();

}

// обработка нажатия кнопки "Выбор файла"

private void Browse_Click(object sender, EventArgs e)

{

/* создание объекта класса для диалога открытия защищенного файла */

openFileDialog1 = new OpenFileDialog();

// определение свойств диалогового окна

// маска имени для отображаемых в окне файлов

openFileDialog1.Filter = "Все файлы (*.*)|*.*";

/* проверка существования файла с введенным пользователем именем до закрытия диалога */

openFileDialog1.CheckFileExists = true;

// выбор в качестве начальной папки текущую

openFileDialog1.InitialDirectory = Directory. GetCurrentDirectory();

// восстановление текущей папки после закрытия диалога

openFileDialog1.RestoreDirectory = true;

// если пользователь выбрал файл

if (openFileDialog1.ShowDialog() == DialogResult. OK)

// сохранение и отображение имени выбранного файла

InputFName. Text = openFileDialog1.FileName;

}

// обработка изменения текста в строке с именем защищенного файла

private void InputFName_TextChanged(object sender, EventArgs e)

{

// если имя защищенного файла введено и такой файл существует,

// то разблокирование кнопки "Подписать"

Sign. Enabled = InputFName. Text. Length > 0 &&

File. Exists(InputFName. Text);

// если существуют защищенный файл, файлы с ЭЦП

// и открытым ключом, то разблокировка кнопки "Проверить ЭЦП"

Verify. Enabled = InputFName. Text. Length > 0 &&

File. Exists(InputFName. Text) &&

File. Exists(InputFName. Text+".sig") &&

File. Exists(InputFName. Text+".pub");

}

// обработка нажатия кнопики «Подписать»

private void Sign_Click(object sender, EventArgs e)

{

try

{

/* отображение имени файла с ЭЦП (к имени исходного файла добавляется расширение. sig) */

SigFName. Text = InputFName. Text + ".sig";

/* отображение имени файла с открытым ключом (к имени исходного файла добавляется расширение. pub) */

PubFName. Text = InputFName. Text + ".pub";

// создание объектов для файловых потоков

finStream = new FileStream(InputFName. Text, FileMode. Open);

fsigStream = new FileStream(SigFName. Text, FileMode. Create);

fpubStream = new FileStream(PubFName. Text, FileMode. Create);

/* хеширование и вычисление ЭЦП для данных из входного потока */

sigbytes = dsa. SignData(finStream);

// сохранение ЭЦП в файле

fsigStream. Write(sigbytes, 0, sigbytes. Length);

// экспорт открытого ключа

key = dsa. ExportCspBlob(false);

// сохранение открытого ключа в файле

fpubStream. Write(key,0,key. Length);

// разблокировка кнопки "Проверить ЭЦП"

Verify. Enabled = true;

// закрытие файлов

finStream. Close();

fsigStream. Close();

fpubStream. Close();

}

// обработка ошибки криптографической операции

catch (CryptographicException ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

// закрытие файлов

finStream. Close();

fsigStream. Close();

fpubStream. Close();

}

// обработка остальных ошибок

catch (Exception ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

}

}

// обработка нажатия кнопки «Проверить ЭЦП»

private void Verify_Click(object sender, EventArgs e)

{

try

{

/* отображение имени файла с ЭЦП (к имени исходного файла добавляется расширение. sig */

SigFName. Text = InputFName. Text + ".sig";

/* отображение имени файла с открытым ключом(к имени исходного файла добавляется расширение. pub) */

PubFName. Text = InputFName. Text + ".pub";

// создание объектов для файловых потоков

finStream = new FileStream(InputFName. Text, FileMode. Open);

fsigStream = new FileStream(SigFName. Text, FileMode. Open);

fpubStream = new FileStream(PubFName. Text, FileMode. Open);

// получение длины ЭЦП

numBytesToRead=(int)fsigStream. Length;

// выделение памяти для буфера ЭЦП

sigbytes = new byte[fsigStream. Length];

// чтение ЭЦП из файла

fsigStream. Read(sigbytes,0,numBytesToRead);

// получение длины открытого ключа

numBytesToRead=(int)fpubStream. Length;

// выделение памяти для блоба с открытым ключом

key = new byte[fpubStream. Length];

// чтение открытого ключа из файла

fpubStream. Read(key,0,numBytesToRead);

// получение длины защищенного файла

numBytesToRead=(int)finStream. Length;

// выделение памяти для буфера ввода

bytes = new byte[finStream. Length];

// чтение данных из защищенного файла

finStream. Read(bytes,0,numBytesToRead);

// импорт открытого ключа

dsa. ImportCspBlob(key);

// проверка ЭЦП из файла для данных из файлового потока

if(dsa. VerifyData(bytes, sigbytes))

MessageBox. Show("Подпись верна!",

"Результат проверки ЭЦП");

else MessageBox. Show("Подпись не верна!",

"Результат проверки ЭЦП");

// закрытие файлов

finStream. Close();

fsigStream. Close();

fpubStream. Close();

}

// обработка ошибки криптографической операции

catch (CryptographicException ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

// закрытие файлов

finStream. Close();

fsigStream. Close();

fpubStream. Close();

}

// обработка остальных ошибок

catch (Exception ex)

{

// вывод сообщения об ошибке

MessageBox. Show(ex. Message, "Ошибка", MessageBoxButtons. OK,

MessageBoxIcon. Error);

}

}

}

}

Во втором примере рассмотрим получение и проверку ЭЦП под сообщениями с помощью криптоалгоритм RSA и функции хеширования MD5. На рис. 5 приведено главное окно программы, а в табл. 4 указано соответствие между элементами управления окна и объектами программы.

Ниже приведен текст программы:

using System;

using System. Collections. Generic;

using ponentModel;

using System. Data;

using System. Drawing;

using System. Linq;

using System. Text;

using System. Windows. Forms;

// подключение пространства имен криптографических классов

using System. Security. Cryptography;

// подключение пространства имен для классов работы с памятью

using System. IO;

Рис. 5. Главное окно программы для подписания сообщений

Таблица 4

Имена объектов программ для элементов управления

Элемент управления окна

Его имя в программе

Редактор для ввода текста сообщения

Message

Строка для отображения подписи

Signature

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

KeyLen

Кнопка «Подписать»

Sign

Кнопка «Проверить ЭЦП»

Verify

Кнопка «Закрыть»

Exit

namespace WindowsFormsApplication5

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15