{
public partial class Form1 : Form
{
// объект класса алгоритма ЭЦП
RSACryptoServiceProvider rsa;
// объект класса для потока данных в оперативной памяти
MemoryStream msSigned;
// буфер для массива байт подписываемой строки
byte[] toSign;
// буфер для массива байт ЭЦП
byte[] sigBytes;
// длина ключа
int KeyLength;
// конструктор класса формы главного окна программы
public Form1()
{
InitializeComponent();
// создание объекта для криптоалгоритма
rsa = new RSACryptoServiceProvider();
// создание объекта для параметров разрешенной длины ключа
KeySizes[] ks = rsa. LegalKeySizes;
// максимально возможная для выбора длина ключа
KeyLen. Maximum = ks[0].MaxSize;
// минимально возможная длина ключа
KeyLen. Minimum = ks[0].MinSize;
// длина ключа по умолчанию
KeyLen. Value = rsa. KeySize;
// шаг изменения длины ключа
KeyLen. Increment = ks[0].SkipSize;
}
// обработка нажатия кнопки "Закрыть"
private void Exit_Click(object sender, EventArgs e)
{
// закрытие главного окна
Close();
}
// обработка изменения текста сообщения
private void Message_TextChanged(object sender, EventArgs e)
{
// блокирование кнопки "Подписать", если сообщение не введено
Sign. Enabled = Message. Text. Length!= 0;
}
// обработка изменения значения подписи
private void Signature_TextChanged(object sender, EventArgs e)
{
/* блокирование кнопки "Проверить ЭЦП", если подпись не получена */
Verify. Enabled = Signature. Text. Length!= 0;
}
// обработка нажатия кнопки "Подписать"
private void Sign_Click(object sender, EventArgs e)
{
// очистка редактора с подписью
Signature. Clear();
// декодирование введенной строки открытого текста
toSign = Encoding. Unicode. GetBytes(Message. Text);
// создание объекта для потока данных в оперативной памяти
msSigned = new MemoryStream(toSign);
// полученние выбранной длины ключа
KeyLength = (int)KeyLen. Value;
// задание длины ключа ЭЦП
rsa. KeySize = KeyLength;
// вычисление ЭЦП для сообщения
sigBytes = rsa. SignData(msSigned, "MD5");
// отображение подписи
Signature. Text = Encoding. Unicode.
GetString(sigBytes, 0, sigBytes. Length);
// блокирование кнопки "Подписать"
Sign. Enabled = false;
// блокировка элемента для выбора длины ключа подписи
KeyLen. Enabled = false;
// закрытие потока в памяти
msSigned. Close();
}
// обработка нажатия кнопки "Проверить ЭЦП"
private void Verify_Click(object sender, EventArgs e)
{
// получение подписанного сообщения
toSign = Encoding. Unicode. GetBytes(Message. Text);
// проверка подписи с выводом сообщения о результате проверки
if (rsa. VerifyData(toSign, "MD5", sigBytes))
MessageBox. Show("Подпись верна", "Проверка подписи");
else MessageBox. Show("Подпись не верна", "Проверка подписи");
// разблокировка кнопки "Подписать"
Sign. Enabled = true;
}
}
}
Заметим, что в приведенной выше программе не требуется сохранения и восстановления открытого ключа проверки подписи, поскольку вычисление и проверка ЭЦП производятся за один сеанс работы с программой.
В третьем примере мы изменим программу из второго примера раздела 1.2, чтобы показать совместное использование классов RSACryptoServiceProvider, RSAOAEPKeyExchangeFormatter и RSAOAEPKeyExchangeDeformatter для сохранения и восстановления случайного секретного ключа симметричного шифрования. Ниже приведен измененный текст программы.
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 WindowsFormsApplication2
{
public partial class Form1 : Form
{
// объект класса для симметричного криптоалгоритма
AesManaged Aes;
// длина секретного ключа симметричного шифрования
int KeyLength;
// объект класса для потока данных в оперативной памяти
MemoryStream msEncrypt;
// объект для криптографического потока данных
CryptoStream csEncrypt;
// буфер для массива байт шифруемой строки
byte[] toEncrypt;
// буфер для массива расшифрованных байт
byte[] encrypted;
// массив данных для списка возможных значений длины ключа
int[] ksizes;
/* объект для асимметричного криптоалгоритма передачи секретного ключа */
RSACryptoServiceProvider rsa;
// зашифрованный секретный ключ
byte[] encKey;
// конструктор класса формы главного окна программы
public Form1()
{
InitializeComponent();
//создание объекта для алгоритма симметричного шифрования
Aes = new AesManaged();
// получение случайного начального вектора
Aes. GenerateIV();
// установка режима блочного шифрования
Aes. Mode = CipherMode. CBC;
// массив допустимых значений длины ключа
KeySizes[] ks=Aes. LegalKeySizes;
// получение минимально возможной длины ключа
KeyLength = ks[0].MinSize;
// индексы элемента списка и выделенного элемента
int i = 0, isel = 0;
// максимальная длина ключа и длина ключа по умолчанию
int ksmax = ks[0].MaxSize, ksdef = Aes. KeySize;
// создание массива данных для списка
ksizes = new int[3];
// заполнение списка возможных значений длины ключа
do
{
ksizes[i] = KeyLength;
// сохранение индекса для длины ключа по умолчанию
if (KeyLength == ksdef)
isel = i;
// увеличение возможной длины ключа
KeyLength += ks[0].SkipSize;
i++;
}
while (KeyLength <= ksmax);
// связывание списка с массивом данных
KeyLen. DataSource = ksizes;
// выделение элемента списка
KeyLen. SelectedIndex = isel;
}
// обработка нажатия кнопки "Выход"
private void Exit_Click(object sender, EventArgs e)
{
// закрытие главного окна
Close();
}
// обработка изменения открытого текста
private void PlainText_TextChanged(object sender, EventArgs e)
{
/* блокирование кнопки "Зашифровать", если открытый текст не введен */
Encrypt. Enabled = PlainText. Text. Length!= 0;
}
// обработка изменения шифротекста
private void CipherText_TextChanged(object sender, EventArgs e)
{
/* блокирование кнопки "Расшифровать", если шифротекст не получен */
Decrypt. Enabled = CipherText. Text. Length!= 0;
}
// обработка нажатия кнопки "Зашифровать"
private void Encrypt_Click(object sender, EventArgs e)
{
// буфер для случайного секретного ключа
byte[] key;
/* созждание объекта для асимметричного криптоалгоритма обмена ключами */
rsa=new RSACryptoServiceProvider();
// создание объекта для сохранения секретного ключа
RSAOAEPKeyExchangeFormatter keyExch =
new RSAOAEPKeyExchangeFormatter(rsa);
// очистка редактора с шифротекстом
CipherText. Clear();
// создание объекта для потока данных в оперативной памяти
msEncrypt = new MemoryStream();
// получение введенной строки открытого текста
toEncrypt = Encoding. Unicode. GetBytes(PlainText. Text);
// полученние выбранной длины ключа
KeyLength = ksizes[KeyLen. SelectedIndex];
// задание длины секретного ключа
Aes. KeySize = KeyLength;
// создание объекта для генерации случайного ключа
RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
// выделение памяти под случайный ключ
key = new byte[KeyLength/8];
// получение случайного ключа
rand. GetBytes(key);
// задание секретного ключа для шифрования
Aes. Key = key;
// создание объекта для выполнения шифрования потока
ICryptoTransform encryptor = Aes. CreateEncryptor(Aes. Key, Aes. IV);
// создание объекта для криптографического потока
csEncrypt = new CryptoStream(msEncrypt, encryptor,
CryptoStreamMode. Write);
// шифрование открытого текста
csEncrypt. Write(toEncrypt, 0, toEncrypt. Length);
// закрытие криптографического потока
csEncrypt. Close();
// получение шифротекста
encrypted = msEncrypt. ToArray();
// отображение шифротекста
CipherText. Text = Encoding. Unicode.
GetString(encrypted, 0, encrypted. Length);
// сохранение зашифрованного секретного ключа
encKey = keyExch. CreateKeyExchange(Aes. Key);
// блокирование кнопки "Зашифровать"
Encrypt. Enabled = false;
// блокирование списка для выбора длины ключа
KeyLen. Enabled = false;
// закрытие потока в памяти
msEncrypt. Close();
}
// обработка нажатия кнопки "Расшифровать"
private void Decrypt_Click(object sender, EventArgs e)
{
// создание объекта для восстановления секретного ключа
RSAOAEPKeyExchangeDeformatter keyExch =
new RSAOAEPKeyExchangeDeformatter(rsa);
// восстановление секретного ключа
Aes. Key = keyExch. DecryptKeyExchange(encKey);
// очистка строки с открытым текстом
PlainText. Clear();
// создание объекта для выполнения расшифрования потока
ICryptoTransform decryptor = Aes. CreateDecryptor(Aes. Key, Aes. IV);
// получение шифротекста
encrypted = Encoding. Unicode. GetBytes(CipherText. Text);
// создание объекта для данных в оперативной памяти
msEncrypt = new MemoryStream(encrypted);
// создание объект для криптографического потока
csEncrypt = new CryptoStream(msEncrypt, decryptor,
CryptoStreamMode. Read);
// выделение памяти для расшифрованногог текста
toEncrypt = new byte[encrypted. Length];
// расшифрование данных
csEncrypt. Read(toEncrypt, 0, encrypted. Length);
// отображение расшифрованного открытого текста
PlainText. Text = Encoding. Unicode.
GetString(toEncrypt, 0, toEncrypt. Length);
// закрытие криптографического потока
csEncrypt. Close();
// блокирование кнопки "Расшифровать"
Decrypt. Enabled = false;
// закрытие потока в памяти
msEncrypt. Close();
}
}
}
Глава 3
Средства хеширования и обеспечения целостности данных
3.1. Классы алгоритмов хеширования
В состав библиотеки FCL входят классы для реализации следующих функций хеширования, используемых совместно с асимметричными криптоалгоритмами в механизме электронной цифровой подписи, а также при контроле целостности информации:
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |


