
- •Int main (void)
- •Void md5Init (md5_ctx *);
- •Void md5Update (md5_ctx *, unsigned char *, unsigned int);
- •Void md5Final (unsigned char [16], md5_ctx *);
- •0X80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- •0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- •0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- •Void md5Init (md5_ctx *context)
- •II (a, b, c, d, X[ 0], s41, 0xf4292244); /* 49 */
- •900150983Cd24fb0d6963f7d28e17f72
- •Библиографический список
ПРАКТИЧЕСКАЯ ЧАСТЬ
Пример 2. В MS Visual Studio на языке Си написать программу хэширования сообщения «abc» (латинские буквы) с помощью стандарта MD5.
Программный код решения примера
(состоит из нескольких функций)
/*
* Пример реализации стандарта хэширования MD5
* в Microsoft Visual Studio на языке С
* Авторы: Сидоров Д.П., Афонин В.В., доценты кафедры АСОИУ
* МГУ им. Н.П. Огарева
*/
// 1-я функция (например, main.c)
// Главная функция
#include <stdio.h>
#include <conio.h>
#include <string.h>
// Заголовочный файл к проекту хэширования MD5
#include "hMD5.h"
Int main (void)
{
// Тестовый пример
unsigned char ptext[] = "abc"; // исходное сообщение
// Длина сообщения в байтах
unsigned int len = (unsigned )strlen((const char *)ptext);
unsigned char digest[16]; // дайджест сообщения
int i;
// Создание переменной структурного типа
// с произвольной инициализацией
MD5_CTX con = { 1, 2, 3, 4, 5, 6, "123"};
// Создание указателя на переменную структурного типа
MD5_CTX *context = &con;
// Вывод на консоль исходного сообщения
printf("\n Original Post:\n %s\n", ptext);
// Размер исходного сообщения в байтах
printf("\n The number of bytes in the text: ");
printf("len = %u\n", strlen((const char *)ptext) );
// Обращение к функциям хэширования
MD5Init (context);
MD5Update (context, ptext, len);
MD5Final (digest, context);
// Вывод на консоль результата хэширования
printf("\n Message digest:\n ");
for ( i = 0; i < 16; ++i )
{
printf("%02x", digest[i]);
///_getch(); // для шагового просмотра
}
// Примечание
// %02x - вывод шестнадцатеричных чисел с одним ведущим нулем
// и двух позиций под число, так как 1 байт - это две
// шестнадцатеричные цифры
printf("\n\n Press any key: ");
_getch();
return 0;
}
// 2-й файл (например, hMD5.h)
// Заголовочный файл к проекту хэширования MD5
// POINTER определяет базовый тип указателя
typedef unsigned char *POINTER;
// UINT4 определяет 4-байтовое слово
typedef unsigned long int UINT4;
// Структура - контекст стандарта MD5
typedef struct {
UINT4 state[4]; // состояние (ABCD)
UINT4 count[2]; // число бит, конгруэнтных значению 2^64
//(сначала младший)
unsigned char buffer[64]; // входной буфер
} MD5_CTX; // имя структурной переменной
// Прототип функции инициализации контекста MD5
Void md5Init (md5_ctx *);
// Прототип функции основных операций хэширования стандарта MD5
Void md5Update (md5_ctx *, unsigned char *, unsigned int);
// Прототип функции заключительного этапа хэширования
// стандарта MD5
Void md5Final (unsigned char [16], md5_ctx *);
// Стандартные константы сдвига в раундах хэширования
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
// Прототип функции преобразования
static void MD5Transform (UINT4 [4], unsigned char [64]);
// Прототип функции кодирования
static void Encode (unsigned char *, UINT4 *, unsigned int);
// Прототип функции декодирования
static void Decode (UINT4 *, unsigned char *, unsigned int);
// Прототип функции копирования байтов
static void MD5_memcpy (POINTER, POINTER, unsigned int);
// Прототип функции копирования и распределения байтов
static void MD5_memset (POINTER, int, unsigned int);
// Массив дополнения
static unsigned char PADDING[64] = {
0X80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
// 0х80 - шестнадцатеричное число или число 128, что в двоичной
// системе равно 10000000
/*
* F, G, H, I - основные функции MD5,
* выполнены в виде макросов
*/
#define F( x, y, z ) ( ((x) & (y)) | ((~x) & (z)) )
#define G( x, y, z ) ( ((x) & (z)) | ((y) & (~z)) )
#define H( x, y, z ) ( (x) ^ (y) ^ (z) )
#define I( x, y, z ) ( (y) ^ ((x) | (~z)) )
// Функция-макрос по вращению битов (х) влево
// на заданное число n
#define ROTATE_LEFT( x, n ) ( ((x) << (n)) | ((x) >> (32-(n))) )
/*
* FF, GG, HH, и II - стандартные макросы преобразования для раундов 1, 2, 3, и 4
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
// 3-й файл (например, MD5.c)
// Определения функций хэширования стандарта MD5
#include "hMD5.h" // подключение заголовочного файла