Цифровая подписьРефераты >> Программирование и компьютеры >> Цифровая подпись
ROTATE_LEFT
Данный макрос сдвигает x влево на n бит.
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
Если n > 32,то результат равен нулю.
Функции
void MD5Init ( MD5_CTX *mdContext)
Функция MD5Init(MD5_CTX *mdContext) выполняет инициализацию некоторых полей структуры Message Digest MD5_CTX В качестве параметра функция получает указатель на структуру MD5_CTX.
{
/* Обнуление полей, которые будут содержать длину сообщения */
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
/* Загрузка магических констант инициализации. */
mdContext->buf[0] = (UINT4)0x67452301L;
mdContext->buf[1] = (UINT4)0xefcdab89L;
mdContext->buf[2] = (UINT4)0x98badcfeL;
mdContext->buf[3] = (UINT4)0x10325476L;
}
void MD5Update (register MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
Данная функция обрабатывает содержимое структуры MD5_CTX.
В качестве параметров функция получает:
Указатель mdContext на структуру MD5_CTX;
Cимвольный буфер inBuf[],который содержит символы исходного сообщения,чей Message Digest мы подсчитываем; Длину inLen передаваемого буфера.
Вначале подсчитывается целочисленная величина mdi:
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
Эта величина равна длине сообщения в байтах по модулю 64.Длина сообщения в битах хранится в структуре MD5_CTX в буфере i[0 1].
Длина сообщения в битах заносится в буфер i[0 1] следующим образом:
mdContext->i[0] += ((UINT4)inLen << 3);
mdContext->i[1] += ((UINT4)inLen >> 29);
Следующий участок кода выполняет следующие действия:
while (inLen--)
{
/* добавляем новый символ в буфер, инкрементируя mdi */
mdContext->in[mdi++] = *inBuf++;
/* Если необходимо выполняем преобразование */
if (mdi == 0x40)
{
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
mdi = 0;
}
}
Пока уменьшаемая на 1 длина переданного в функцию сообщения не станет равной нулю выполняем следующие действия:
Заносим новый символ из входного буфера функции в 64-х байтный буфер структуры MD5_CTX,увеличивая при этом переменную mdi на 1. Если mdi равна 64, то преобразуем
однобайтные символы буфера in[] стуктуры MD5_CTX в 4-х байтные величины типа UINT4, заносим в промежуточный буфер на 16 величин типа UINT4, и далее передаем функции Transform().Присваиваем переменной mdi 0.
void MD5Final (MD5_CTX *mdContext)
Функция завершает вычисление Message Digest и заносит полученное значение в структуре MD5_CTX в символьный буфер digest[0 .15].
Входным параметром функции является указатель на структуру MD5_CTX.
Основные моменты:
Расширение сообщения дополнительными заполняющими символами из таблицы PADDING[]
/* Подсчет длины сообщения в байтах по модулю 64 */
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
/* Расширить до 56 по модулю 64 */
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
MD5Update(mdContext, PADDING, padLen);
Присоединение битов длины и вызов функции Transform().
in[14] = mdContext->i[0];
in[15] = mdContext->i[1];
for (i = 0, ii = 0; i < 14; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
Сохранение буфера в digest(т.е.получение окончательного Message Digest):
for (i = 0, ii = 0; i < 4; i++, ii += 4)
{
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
}
void Transform(register UINT4 *buf,register UINT4 *in)
Данная функция является основным шагом в алгоритме MD5.
Входными параметрами являются указатель на буфер buf[] из структуры MD5_CTX и указатель на буфер in[], хранящем значения типа UINT4. Функция выполняет 4 цикла по 16 шагов в каждом. В каждом цикле используется одна из функций FF, GG, HH, II. Далее окончательный результат после 64-х преобразовательных итераций добавляется к содержимому буфера buf[].
Структура MD5_CTX
Структура MD5_CTX является основной структурой для формирования MessageDigest. Структура содержит следующие поля:
typedef struct
{
UINT4 i[2]; /* количество бит в сообщении по mod 2^64 */
UINT4 buf[4]; /* временный буфер */
unsigned char in[64]; /* входной буфер */
unsigned char digest[16]; /* содержит действительный Message Digest
после вызова MD5Final() */
} MD5_CTX;
Цифровая подпись и криптосистемы с ключом общего пользования.
Если использовать алгоритмы хэширования вместе с криптосистемами с ключом общего пользования, то можно создать цифровую подпись, гарантирующую подлинность полученного набора данных, аналогично тому, как рукописная подпись, подтверждает аутентичность напечатонного документа. Криптосистема с ключом общего пользования - это метод, позволяющий осуществлять кодирование и декодирование информации, с помощью двух исходных ключей: ключа общего пользования, свободно передаваемого всем желающим, и личного ключа, известного только его владельцу.
Смысл ключа и пароля примерно одинаков. Допустим, Том желает, чтобы Сэм мог отправить ему зашифрованный документ, и оба они не хотели бы рисковать, передавая пароль или ключ по линиям связи, так как в этом случае он может быть кем-то перехвачен. Тогда Том может передать Сэму свой ключ общего пользования (схема 1).
Используя этот ключ, Сэм шифрует документ и отправляет его Тому. Том дешифрует документ с помощью своего личного ключа. Это единственный ключ, с помощью которого можно восстановить документ, зашифрованный с применением ключа общего пользования, принадлежащего Тому. Тот факт, что ключ общего пользования Тома может стать кому-то известен, не имеет особого значения, потому что он абсолютно бесполезен для расшифровки документа. А личный ключ, известный одному лишь Тому, по открытым линиям связи не передавался; теоретически том хранит его только в собственной памяти и наоборот, работа других криптосистем с ключом общего пользования строится на обратном принципе: Сэм шифрует документ с помощью своего личного ключа и передает свой ключ общего пользования Тому, с помощью которого тот мог бы расшифровать этот документ. Существующие ныне криптосистемы с ключом общего пользования, такие, например, как система RSA (сокращение, составленное из первых букв фамилий трех создателей этого алгоритма), широко используются.