{

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