Реализация алгоритма Диффи-Хеллмана в .NET Framework
Алгоритм безопасного распределения ключей Диффи-Хеллмана реализован с помощью класса ECDiffieHellmanCng пространства имен System.Security.Cryptography. Класс ECDiffieHellmanCng позволяет двум сторонам обмениваться секретными ключами, даже если взаимодействие осуществляется по открытому каналу.
Алгоритм Диффи-Хеллмана в System.Security.Cryptography использует, так называемые, новые классы, реализованные, начиная с версии .NET Framework 3.5. Причем, начиная с версии ОС Windows 7. Новые классы имеют префикс (или суффикс) Cng, который представляет собой сокращение от Cryptography Next Generation (криптография следующего поколения).
Свойства и методы класса ECDiffieHellmanCng
Свойства класса ECDiffieHellmanCng приведены в таблице 4.1, а методы в таблице 4.2.
Таблица 4.1 – Свойства класса ECDiffieHellmanCng
№ | Свойство | Описание |
1 | HashAlgorithm | Получает или задает хэш-алгоритм, используемый при генерации ключевого материала |
2 | HmacKey | Получает или задает ключ HMAC, используемый при формировании ключевого материала. |
3 | Key | Задает объект CngKey, который будет использоваться текущим объектом для выполнения криптографических операций |
4 | KeyDerivationFunction | Получает или задает функцию формирования ключа для класса ECDiffieHellmanCng |
5 | KeyExchangeAlgorithm | Получает имя алгоритма обмена ключами |
6 | KeySize | Получает или задает размер ключа (в битах), используемого алгоритмом асимметричного шифрования |
7 | Label | Получает или задает значение метки, используемой для формирования ключа |
8 | LegalKeySizes | Возвращает размеры ключа, которые поддерживаются алгоритмом асимметричного шифрования |
9 | PublicKey | Получает открытый ключ, который может использоваться другим объектом ECDiffieHellmanCng для генерации секретного соглашения |
10 | SecretAppend | Получает или задает значение, добавляемое к концу секретного соглашения при генерации ключевого материала |
11 | SecretPrepend | Получает или задает значение, добавляемое к началу секретного соглашения при формировании ключевого материала |
12 | Seed | Получает или задает начальное значение, используемое при формировании ключевого материала. |
13 | SignatureAlgorithm | Получает имя алгоритма подписи |
|
|
Таблица 4.2 – Методы класса ECDiffieHellmanCng
№ | Свойство | Описание |
1 | Clear() | Освобождает все ресурсы, используемые классом AsymmetricAlgorithm |
2 | DeriveKeyMaterial (CngKey) | Формирует ключевой материал из секретного соглашения, заключенного между двумя сторонами, используя заданный объект CngKey, в котором содержится открытый ключ второй стороны |
3 | DeriveKeyMaterial (ECDiffieHellmanPublicKey) | Формирует ключевой материал из секретного соглашения, заключенного между двумя сторонами, используя заданный объект ECDiffieHellmanPublicKey, в котором содержится открытый ключ второй стороны |
4 | DeriveSecretAgreemantHandle (CngKey) | Получает дескриптор секретного соглашения, заключенного между двумя сторонами, используя заданный объект CngKey, в котором содержится открытый ключ второй стороны |
5 | DeriveSecretAgreemantHandle (ECDiffieHellmanPublicKey) | Получает дескриптор секретного соглашения, согласованного между двумя сторонами, используя заданный объект ECDiffieHellmanPublicKey, в котором содержится открытый ключ второй стороны |
6 | Dispose() | Освобождает все ресурсы, используемые текущим экземпляром классаAsymmetricAlgorithm |
7 | Equals(Object) | Определяет, равен ли заданный объект текущему объекту |
8 | ToString() | Возвращает строковое представление текущего объекта |
Пример программной реализации алгорима Диффи-Хеллмана
|
|
В качестве примера программной реализации алгоритма Диффи-Хеллмана рассмотрим приложение, изображенное на рисунке 4.1. В таблице 4.3 приведено описание используемых в приложении элементов управления.
Таблица 4.3 - Элементы управления
Элемент управления | Класс | Описание |
1 | 2 | 3 |
groupBox1 | GroupBox | Панель группировки «Генерация ключей» |
groupBox2 | GroupBox | Панель группировки «Пользователь А» |
groupBox3 | GroupBox | Панель группировки «Пользователь В » |
textBox1 | TextBox | Окно вывода открытого ключа пользователя А |
Продолжение таблицы 4.3
|
|
textBox2 | TextBox | Окно вывода открытого ключа пользователя В |
textBox3 | TextBox | Окно ввода сообщения, передаваемого пользователем А пользователю В |
textBox4 | TextBox | Окно вывода симметричного ключа, сформированного пользователем А |
textBox5 | TextBox | Окно вывода зашифрованного сообщения |
textBox6 | TextBox | Окно вывода полученного пользователем В зашифрованного сообщения |
textBox7 | TextBox | Окно вывода симметричного ключа, сформированного пользователем В |
textBox8 | TextBox | Окно вывода дешифрованного сообщения (полученного пользователем В от пользователя А) |
Как видно из рисунка 4.1 пользователи А и В сформировании один и тот же симметричный ключ на основании полученного друг от друга исходного материала.
Последовательность программирования приложения:
1. Подключение пространства имен System.Security.Cryptography и System.IO:
using System.IO;
using System.Security.Cryptography;
1. Объявление глобальных переменных:
// Глобальные переменные
// Секретный ключ пользователя А
static CngKey aKey;
// Секретный ключ пользователя В
static CngKey bKey;
|
|
// Открытый ключ пользователя А
static byte[] aPubKeyBlob;
// Открытый ключ пользователя В
static byte[] bPubKeyBlob;
// Передаваемые данные
byte[] encryptedData;
2. Функция формирования ключей пользователей А и В:
private static void CreateKeys()
{
aKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
bKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
aPubKeyBlob = aKey.Export(CngKeyBlobFormat.EccPublicBlob);
bPubKeyBlob = bKey.Export(CngKeyBlobFormat.EccPublicBlob);
}
3. Событие Click кнопки button1 (Генерировать):
private void button1_Click(object sender, EventArgs e)
{
CreateKeys();
textBox1.Text =Convert.ToBase64String(aPubKeyBlob);
textBox2.Text =Convert.ToBase64String(bPubKeyBlob);
}
4. Событие Click кнопки button2 (Передать):
private void button2_Click(object sender, EventArgs e)
{
// Шифруемое сообщение
string message=textBox3.Text;
// Преобразование строки шифруемого текста в
// массив байтов
byte[] rawData = Encoding.UTF8.GetBytes(message);
encryptedData = null;
// Создание объекта ECDiffieHellmanCng и
// инициализация его с помощью ключей
// пользователя А
ECDiffieHellmanCng aAlgorithm = new ECDiffieHellmanCng(aKey);
using (CngKey bPubKey = CngKey.Import(bPubKeyBlob, CngKeyBlobFormat.EccPublicBlob))
{
// Пользователь А создает симметричный ключ
// путем импользования своей пары ключей и
// открытого ключа пользователя В, вызывая
// метод DeriveKeyMaterial()
byte[] symmKey = aAlgorithm.DeriveKeyMaterial(bPubKey);
textBox4.Text = Convert.ToBase64String(symmKey);
// Созданный симметричный ключ используется с
// алгоритмом AES для шифрования сообщения,
// передаваемого пользователю В
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.Key = symmKey;
// Динамическая генерация начального вектора IV
aes.GenerateIV();
using (ICryptoTransform encryptor=aes.CreateEncryptor())
using (MemoryStream ms = new MemoryStream())
{
// создается CryptoStream и шифруются
// подлежащие отправке данные
CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
// Записывается вектор инициализации IV
//не шифруя
ms.Write(aes.IV,0, aes.IV.Length);
cs.Write(rawData,0,rawData.Length);
cs.Close();
encryptedData = ms.ToArray();
textBox5.Text = Convert.ToBase64String(encryptedData);
}
aes.Clear();
}
}
5. Событие Click кнопки button3 (Получить):
private void button3_Click(object sender, EventArgs e)
{
textBox6.Text = Convert.ToBase64String(encryptedData);
byte[] rawData = null;
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
// Свойство BlockSize класса
// AesCryptoServiceProvider возвращает количество
// битов в полученном блоке.
// Количество байтов получается делением на 8
int nBytes = aes.BlockSize >> 3;
// Извлекается вектор инициализации
byte[] iv = new byte[nBytes];
for (int i = 0; i < iv.Length; i++)
iv[i] = encryptedData[i];
// Создание объекта ECDiffieHellmanCng и
// инициализация его с помощью ключей
// пользователя В
ECDiffieHellmanCng bAlgorithm = new ECDiffieHellmanCng(bKey);
using (CngKey aPubKey = CngKey.Import(aPubKeyBlob, CngKeyBlobFormat.EccPublicBlob))
{
// Пользователь В создает симметричный ключ
// путем импользования своей пары ключей и
// открытого ключа пользователя А, вызывая
// метод DeriveKeyMaterial()
byte[] symmKey = bAlgorithm.DeriveKeyMaterial(aPubKey);
textBox7.Text = Convert.ToBase64String(symmKey);
aes.Key = symmKey;
aes.IV = iv;
// Дешифрование полученного сообщения с помощью
// симметричного ключа symmKey
using (ICryptoTransform decryptor=aes.CreateDecryptor())
using (MemoryStream ms = new MemoryStream())
{
CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
cs.Write(encryptedData, nBytes, encryptedData.Length - nBytes);
cs.Close();
rawData = ms.ToArray();
textBox8.Text = Encoding.UTF8.GetString(rawData);
}
}
aes.Clear();
}
Дата добавления: 2018-08-06; просмотров: 1897; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!