Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
защита данных / Криптография в MS Visual Studio.doc
Скачиваний:
56
Добавлен:
31.03.2015
Размер:
743.42 Кб
Скачать

3.2. Классы для вычисления и проверки кодов аутентификации сообщений

В состав библиотеки FCL входят следующие классы, предназначенные для вычисления кодов аутентификации сообщений (MAC, message authentication code) и контроля целостности информации:

  • на основе хеширования с секретным ключом по алгоритмам MD5, RIPEMD или SHA (абстрактный базовый класс HMAC и его наследники HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384 и HMACSHA512);

  • на основе алгоритма симметричного шифрования TripleDES (класс MACTripleDES).

Общим абстрактным базовым классом для классов контроля целостности является класс KeyedHashAlgorithm, являющийся наследником класса HashAlgorithm. В классе KeyedHashAlgorithm определено дополнительное свойство:

byte[] Key – секретный ключ, используемый при вычислении и проверке кода аутентификации сообщения.

В классе HMAC определены дополнительные свойства:

  • int BlockSizeValue – длина блока, используемого при вычислении хеш-значения, в байтах;

  • string HashName – имя алгоритма хеширования, используемого при вычислении и проверке кода аутентификации сообщения.

Классы HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384 и HMACSHA512 имеют конструкторы без параметров и конструкторы с параметром

byte[] key – секретный ключ, который будет использоваться объектом класса при вычислении и проверке кода аутентификации сообщений.

Класс HMACSHA1 имеет еще один дополнительный конструктор с параметрами

byte[] key, bool useManagedSha1 – создание объекта с заданным секретным ключом и использованием управляемой реализации алгоритма SHA1, если второй параметр равен true, или реализации этого алгоритма в криптопровайдере в неуправляемом коде, если значением второго параметра является false.

Класс MACTripleDES имеет конструктор без параметров, а также конструкторы с параметрами:

  • byte[] rgbKey – создание объекта с заданным параметром секретного ключа;

  • string strTripleDES, byte[] rgbKey – создание объекта с заданной реализацией алгоритма strTripleDES и заданным секретным ключом rgbKey (реализацией алгоритма TripleDES по умолчанию является System.Security.Cryptography.TripleDES).

Длина ключа, используемая объектами класса MACTripleDES, должна быть 8, 16 или 24 байта.

3.3. Использование средств хеширования и контроля целостности

Рассмотрим примеры использования в приложениях для Microsoft .Net классов, реализующих алгоритмы хеширования и вычисления кодов аутентификации сообщений. В первом примере создадим программу для вычисления хеш-значения по алгоритму RIPEMD160 для двух вводимых пользователем сообщений.

На рис. 6 приведено главное окно программы, а в табл. 5 – соответствие между элементами управления главного окна и их именами в программе.

Рис. 6. Окно программы хеширования

Таблица 5

Имена объектов программ для элементов управления

Элемент управления окна

Его имя в программе

Редактор для ввода текста первого сообщения

Message1

Редактор для ввода текста второго сообщения

Message2

Строка для отображения хеш-значения

HashValue

Кнопка «Выход»

Exit

Для отображения вычисленного хеш-значения в шестнадцатеричном формате в программе используется статический метод класса string

string Format(string format, Object arg0) – преобразование значения arg0 в строку в соответствии с форматной строкой format (для отображения значения байта в виде двух шестнадцатеричных цифр с обязательным выводом нуля используется формат "{0,2:X2}").

Чтобы проверить правильность выполненного хеширования в программе символы введенных сообщений преобразуются в кодировку ASCII с помощью одноименного статического свойства класса Encoding и его метода GetBytes, рассмотренного в разделе 1.2.

Ниже приведен текст программы:

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;

namespace WindowsFormsApplication6

{

// класс главного окна

public partial class Form1 : Form

{

// объект для алгоритма хеширования

RIPEMD160Managed ripemd;

// данные из первого сообщения

byte[] bytes1;

// данные из второго сообщения

byte[] bytes2;

// хеш-значение

byte[] hash;

// конструктор класса главного окна

public Form1()

{

InitializeComponent();

// создание объекта хеширования

ripemd = new RIPEMD160Managed();

}

// обработка нажатия кнопки "Выход"

private void Exit_Click(object sender, EventArgs e)

{

Close();

}

/* обработка изменения текста в любом их двух редакторов для ввода сообщений */

private void Message1_TextChanged(object sender, EventArgs e)

{

// очистка поля для отображения хеш-значения

HashValue.Text=»»;

// данные для хеширования

byte[] data;

// получение данных первого сообщения

bytes1=Encoding.ASCII.GetBytes(Message1.Text);

// получение данных второго сообщения

bytes2 = Encoding.ASCII.GetBytes(Message2.Text);

// выделение памяти для хешируемых данных

data=new byte[bytes1.Length+bytes2.Length];

// объединение данных двух сообщений

bytes1.CopyTo(data, 0);

bytes2.CopyTo(data, bytes1.Length);

// получение хеш-значения

hash = ripemd.ComputeHash(data);

// отображение хеш-значения в шестнадцатеричном формате

for(int i=0; i<hash.Length; i++)

HashValue.Text+=string.Format(“{0,2:X2}”, hash[i]);

}

}

}

Во втором примере этого раздела покажем, как в программе на языке C# использовать алгоритмы хеширования, реализации которых отсутствуют в библиотеке FCL. Для этого нам придется использовать функции CryptoAPI, рассмотренные в разделе 1.3, и некоторые дополнительные функции этого интерфейса, такие как CryptCreateHash, CryptHashData и CryptGetHashParam.

Изменим программу из предыдущего примера и будем вычислять хеш-значение двух сообщений по алгоритму MD4 (окно измененной программы приведено на рис. 7).

В этой программе используются еще две константы, передаваемые функциям CryptoAPI и определенные в файле wincrypt.h:

  • 4 (HP_HASHSIZE, значение параметра для получения длины хеш-значения, генерируемого алгоритмом хеширования);

  • 2 (HP_HASHVAL, значение параметра для получения вычисленного хеш-значения);

  • 0x8002 (CALG_MD4, код алгоритма хеширования MD4).

Первые две константы используются при вызове функции CryptGetHashParam, а третья – CryptCreateHash.

Рис. 7. Главное окно программы хеширования

Ниже приведен текст измененной программы из предыдущего примера:

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.Runtime.InteropServices;

namespace WindowsFormsApplication6

{

// класс главного окна

public partial class Form1 : Form

{

// дескриптор криптопровайдера

IntPtr hProv;

// дескриптор объекта хеширования

IntPtr hHash;

// данные из первого сообщения

byte[] bytes1;

// данные из второго сообщения

byte[] bytes2;

// хеш-значение

byte[] hash;

/* определение функций, импортируемых из внешней библиотеки с реализацией криптопровайдера */

// инициализация криптопровайдера

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CryptAcquireContext(ref IntPtr hProv,

string pszContainer, string pszProvaider,

uint dwProvType, uint dwFlags);

// инициализация объекта хеширования

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CryptCreateHash(IntPtr hProv, uint Algid,

IntPtr hKey, uint dwFlags, ref IntPtr hHash);

// хеширование данных

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CryptHashData(IntPtr hHash, byte[] pbData,

uint dwDataLen, uint dwFlags);

// получение хеш-значения

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CryptGetHashParam(IntPtr hHash, uint dwParam,

byte[] pbData, ref uint pdwDataLen, uint dwFlags);

// разрушение объекта хеширования

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CryptDestroyHash(IntPtr hHash);

// освобождение криптопровайдера

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);

// конструктор класса главного окна

public Form1()

{

InitializeComponent();

// инициализация криптопровайдера

if (!CryptAcquireContext(ref hProv, null, null, 1, 0))

/* если первая попытка неудачна, инициализируем криптопровайдер с созданием контейнера ключей */

if (!CryptAcquireContext(ref hProv, null, null, 1, 8))

throw new CryptographicException

("Ошибка при инициализации криптопровайдера.");

}

// обработка нажатия кнопки "Выход"

private void Exit_Click(object sender, EventArgs e)

{

// освобождение криптопровайдера

CryptReleaseContext(hProv, 0);

// закрытие окна программы

Close();

}

/* обработка изменения текста в любом их двух редакторов для ввода сообщений */

private void Message1_TextChanged(object sender, EventArgs e)

{

// длина параметра объекта хеширования

uint hashlen;

// очистка поля для отображения хеш-значения

HashValue.Text="";

// данные для хеширования

byte[] data;

// получение данных первого сообщения

bytes1=Encoding.ASCII.GetBytes(Message1.Text);

// получение данных второго сообщения

bytes2 = Encoding.ASCII.GetBytes(Message2.Text);

// выделение памяти для хешируемых данных

data=new byte[bytes1.Length+bytes2.Length];

// объединение данных двух сообщений

bytes1.CopyTo(data, 0);

bytes2.CopyTo(data, bytes1.Length);

// инициализация объекта хеширования

if(!CryptCreateHash(hProv, 0x8002, (IntPtr)null, 0, ref hHash))

throw new CryptographicException

("Ошибка при инициализации объекта хеширования.");

// хеширование данных

if(!CryptHashData(hHash, data, (uint)data.Length, 0))

throw new CryptographicException

("Ошибка при хешировании данных.");

/* задание длины параметра, получаемого функцией CryptGetHashParam */

hashlen = 4;

// выделение памяти для буфера с получаемой длиной хеш-значения

hash = new byte[hashlen];

// получение длины хеш-значения

if (!CryptGetHashParam(hHash, 4, hash, ref hashlen, 0))

throw new CryptographicException

("Ошибка при получении длины хеш-значения.");

// сохранение полученной длины хеш-значения

uint hashsize = (uint)hash[0];

// выделение памяти для хеш-значения

hash = new byte[hashsize];

// получение вычисленного хеш-значения

if(!CryptGetHashParam(hHash, 2, hash, ref hashsize, 0))

throw new CryptographicException

("Ошибка при получении хеш-значения.");

// отображение хеш-значения в шестнадцатеричном формате

for(int i=0; i<hashsize; i++)

HashValue.Text+=string.Format("{0,2:X2}", hash[i]);

// разрушение объекта хеширования

CryptDestroyHash(hHash);

}

}

}

Соседние файлы в папке защита данных