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 |


