- •Для студентов, обучающихся по направлению
- •Введение
- •Глава 1 Средства обеспечения конфиденциальности данных
- •1.1. Классы, реализующие алгоритмы симметричного шифрования
- •1.2. Использование классов библиотеки fcl для шифрования данных
- •Имена объектов программы для элементов управления
- •Имена объектов программ для элементов управления
- •1.3. Непосредственное обращение к криптопровайдерам в приложениях для Microsoft .Net
- •Глава 2 Средства обмена секретными ключами и обеспечения аутентичности и целостности данных
- •2.1. Классы, реализующие алгоритмы асимметричного шифрования
- •2.2. Классы для вычисления и проверки эцп
- •2.3. Использование классов асимметричной криптографии
- •Имена объектов программ для элементов управления
- •Имена объектов программ для элементов управления
- •Глава 3 Средства хеширования и обеспечения целостности данных
- •3.1. Классы алгоритмов хеширования
- •3.2. Классы для вычисления и проверки кодов аутентификации сообщений
- •3.3. Использование средств хеширования и контроля целостности
- •Имена объектов программ для элементов управления
- •Контрольные вопросы
- •Библиографический список
- •Оглавление
- •Глава 1 7
- •Глава 2 40
- •Глава 3 70
Имена объектов программ для элементов управления
Элемент управления окна |
Его имя в программе |
Редактор для ввода текста сообщения |
Message |
Строка для отображения подписи |
Signature |
Элемент управления для выбора длины ключа |
KeyLen |
Кнопка «Подписать» |
Sign |
Кнопка «Проверить ЭЦП» |
Verify |
Кнопка «Закрыть» |
Exit |
namespace WindowsFormsApplication5
{
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 System.ComponentModel;
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();
}
}
}