Реализация алгоритма Диффи-Хеллмана в .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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!