gifts2017

ХЭШ функция МД5 (MD5)

Опубликовал Olesya Беличенко (OlesyaBelochka) в раздел Администрирование - Системное

MD5 (англ. Message Digest 5) — 128-битный алгоритм хеширования, разработанный профессором Рональдом Л. Ривестом из Массачусетского технологического института (Massachusetts Institute of Technology, MIT) в 1991 году. Предназначен для создания «отпечатков» или «дайджестов» сообщений произвольной длины и последующей проверки их подлинности. Является улучшенной в плане безопасности версией MD4.[1]

 

Алгоритм MD5

Схема работы алгоритма MD5

На вход алгоритма поступает входной поток данных, хеш которого необходимо найти. Длина сообщения может быть любой (в том числе нулевой). Запишем длину сообщения в L. Это число целое и неотрицательное. Кратность каким-либо числам необязательна. После поступления данных идёт процесс подготовки потока к вычислениям.

Ниже приведены 5 шагов алгоритма:

[править]Шаг 1. Выравнивание потока

Сначала дописывают единичный бит в конец потока(байт 0x80), затем необходимое число нулевых бит. Входные данные выравниваются так, чтобы их новый размер L' был сравним с 448 по модулю 512 (L’ = 512 × N + 448). Выравнивание происходит, даже если длина уже сравнима с 448.

[править]Шаг 2. Добавление длины сообщения

В оставшиеся 64 бита дописывают 64-битное представление длины данных (количество бит в сообщении) до выравнивания. Сначала записывают младшие 4 байта. Если длина превосходит 264 − 1, то дописывают только младшие биты. После этого длина потока станет кратной 512. Вычисления будут основываться на представлении этого потока данных в виде массива слов по 512 бит.

[править]Шаг 3. Инициализация буфера

Для вычислений инициализируются 4 переменных размером по 32 бита и задаются начальные значения шестнадцатеричными числами (шестнадцатеричное представление, сначала младший байт):

А = 01 23 45 67;
В = 89 AB CD EF;
С = FE DC BA 98;
D = 76 54 32 10.

В этих переменных будут храниться результаты промежуточных вычислений. Начальное состояние ABCD называется инициализирующим вектором.

Определим ещё функции и константы, которые нам понадобятся для вычислений.

  • Потребуются 4 функции для четырёх раундов. Введём функции от трёх параметров — слов, результатом также будет слово.
1 раунд Fun F(X,Y,Z) = (Xwedge{Y}) vee (neg{X} wedge{Z}).
2 раунд Fun G(X,Y,Z) = (Xwedge{Z}) vee (neg{Z} wedge{Y}).
3 раунд Fun H(X,Y,Z) = X oplus Y oplus Z.
4 раунд Fun I(X,Y,Z) = Y oplus (neg{Z} vee X).
  • Определим таблицу констант T[1..64] — 64-элементная таблица данных, построенная следующим образом: T[i] = int(4294967296 * | sin(i) | ), где 4294967296 = 232.[3]
  • Выровненные данные разбиваются на блоки (слова) по 32 бита, и каждый блок проходит 4 раунда из 16 операторов. Все операторы однотипны и имеют вид: [abcd k s i], определяемый как a = b + ((a + Fun(b,c,d) + X[k] + T[i]) < < < s), где X — блок данных. X[k] = M [n * 16 + k], где k — номер 32-битного слова из n-го 512-битного блока сообщения, и s — циклический сдвиг влево на s бит полученого 32-битного аргумента.

[править]Шаг 4. Вычисление в цикле

Заносим в блок данных элемент n из массива. Сохраняются значения A, B, C и D, оставшиеся после операций над предыдущими блоками (или их начальные значения, если блок первый).

AA = A
BB = B
CC = C
DD = D

Раунд 1

/*[abcd k s i] a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
[ABCD  0 7  1][DABC  1 12  2][CDAB  2 17  3][BCDA  3 22  4]
[ABCD  4 7  5][DABC  5 12  6][CDAB  6 17  7][BCDA  7 22  8]
[ABCD  8 7  9][DABC  9 12 10][CDAB 10 17 11][BCDA 11 22 12]
[ABCD 12 7 13][DABC 13 12 14][CDAB 14 17 15][BCDA 15 22 16]

Раунд 2

/*[abcd k s i] a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
[ABCD  1 5 17][DABC  6 9 18][CDAB 11 14 19][BCDA  0 20 20]
[ABCD  5 5 21][DABC 10 9 22][CDAB 15 14 23][BCDA  4 20 24]
[ABCD  9 5 25][DABC 14 9 26][CDAB  3 14 27][BCDA  8 20 28]
[ABCD 13 5 29][DABC  2 9 30][CDAB  7 14 31][BCDA 12 20 32]

Раунд 3

/*[abcd k s i] a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
[ABCD  5 4 33][DABC  8 11 34][CDAB 11 16 35][BCDA 14 23 36]
[ABCD  1 4 37][DABC  4 11 38][CDAB  7 16 39][BCDA 10 23 40]
[ABCD 13 4 41][DABC  0 11 42][CDAB  3 16 43][BCDA  6 23 44]
[ABCD  9 4 45][DABC 12 11 46][CDAB 15 16 47][BCDA  2 23 48]

Раунд 4

/*[abcd k s i] a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
[ABCD  0 6 49][DABC  7 10 50][CDAB 14 15 51][BCDA  5 21 52]
[ABCD 12 6 53][DABC  3 10 54][CDAB 10 15 55][BCDA  1 21 56]
[ABCD  8 6 57][DABC 15 10 58][CDAB  6 15 59][BCDA 13 21 60]
[ABCD  4 6 61][DABC 11 10 62][CDAB  2 15 63][BCDA  9 21 64]

Суммируем с результатом предыдущего цикла:

A = AA + A
B = BB + B
C = CC + C
D = DD + D

После окончания цикла необходимо проверить, есть ли ещё блоки для вычислений. Если да, то изменяем номер элемента массива (n++) и переходим в начало цикла.

[править]Шаг 5. Результат вычислений

Результат вычислений находится в буфере ABCD, это и есть хеш. Если выводить побайтово начиная с младшего байта A и закончив старшим байтом D, то мы получим MD5 хеш.

[править]

 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
МЛ5
.epf 9,97Kb
31.10.11
253
.epf 9,97Kb 253 Скачать

См. также

PowerTools от 1 000
Подписаться Добавить вознаграждение

Комментарии

1. Сергей Ожерельев (Поручик) 31.10.11 14:12
(0) И что? Копи-пастить из педивикии я тоже умею.
2. Olesya Беличенко (OlesyaBelochka) 31.10.11 15:17
Молодец, тут же дело не в описании, а в том что обработка преобразует обычную строку в ХЭШ строку МД5. На инфорстаре подобного я не нашла.
3. Ийон Тихий (cool.vlad4) 31.10.11 15:33
(2) Есть на инфостарте(и не только на нем), опять поиск на ИС-е работает не очень
4. Ийон Тихий (cool.vlad4) 31.10.11 15:40
Нашел это ...
http://infostart.ru/public/82506/
http://forum.infostart.ru/forum24/topic38820/
я думаю ничего страшного, если будет и (0) .
5. Дмитрий Бухалов (Re:аниматор) 31.10.11 15:49
На проклабе есть для 7.7 мд5. судя по коду это и есть 7.7 переведенная под 8 ку, все функции, методы и комментарии совпадают
6. mark simf (mark-simf) 31.10.11 22:43
Поддерживаю замечание от аниматора:

Цитирую - "На проклабе есть для 7.7 мд5. судя по коду это и есть 7.7 переведенная под 8 ку, все функции, методы и комментарии совпадают"
7. mark simf (mark-simf) 31.10.11 22:43
А вообще таких примочек полно в инете
8. mark simf (mark-simf) 31.10.11 22:44
У меня тоже есть своя наработка, правда что-то не получается ее тут разместить(((((((((
9. Дмитрий Бухалов (Re:аниматор) 01.11.11 11:51
(6) не "аниматор", а "Re:аниматор" = "Реаниматор"
10. Автоматизация Производства (dimanich70) 06.11.11 12:13
Можно поподробнее, как на практике применить и где (1С интересует)?
11. Андрей Мальцев (fonomo0) 08.12.11 12:43
Присоединяюсь к последнему комментатору. Где использовать?
12. stark temp (stark.temp) 19.01.12 12:02
13. Olesya Беличенко (OlesyaBelochka) 24.01.12 17:49
Спасибо за +.. я на практике применяла для следующего случая.. Обмен с сервером статистики для начисления бонусов покупки, если ты используешь бонусную карту.. Т.е при продаже формируется запрос на сервер. В этом запросе для авторизации передаются логин и пароль кассира, который осуществил продажу.. Так вот для того чтобы не так просто было определить пароль разработчики этой учетной системы придумали что сервер должен получать пароль пользователя в виде ХЭШ функции, он его расшифровывает, и проверяет на правильность..соответственно если пароль введен неправильно то бонусы не начисляются. Да я видела на этом сайте различные обработки... Но они почему-то оказались нерабочими..А эта 100% работает правильно!
14. Alexander Petrov (Red1) 24.01.12 18:01
А что мешало найти реализацию МД5 на ява скрипте, и через объект создавать скрипт в 1С, потом передавать туда параметр, а по а получать уже ХЭШ функцию.
Я просто когда надо сделать что-то такое, понял что на 1С фиг что найдешь, а на других языках этого полно. Тот же генератор случайных чисел например.
15. Алексей Бобылкин (alex_bob) 27.01.12 09:03
Спасибо за почти пригодное для меня решение. Однако хочу предупредить, что для паролей, содержащих символы на русском языке, программа будет давать xэш, отличающийся от кода, который давал вариант на 1С77. Это связано с тем, что в 1С8 применяется кодировка UTF, а в 1С77 ANSI и функция КодСимвола() работает по-разному. В частности это касается хэшей паролей пользователей 1С77, которые хранятся в файле USERS.USR
16. Тимур (restuta) 21.02.12 08:35
Где использовать обывателю?
17. maksim.s (Gandalf Белый) 29.04.12 17:34
Да, поддерживаю вопрос, где это можно использовать?
18. Дмитрий Костомаха (b1waver) 30.05.12 10:57
(16) restuta, для идентификации объектов при интеграции 1С с другими системами, например.
19. Альтаир (Altair777) 24.07.12 14:25
(17) maksim.s,

У меня была небольшая подсистема для принудительной смены пароля в 1С8 через определенное время.
И планировалось не разрешать устанавливать уже существующий. Но хранить ранее введенные пароли в открытом виде не есть хорошо. :)
И как раз для таких случаев можно использовать шифрование.
20. Илья Асламов (7fortune) 04.08.12 01:09
что-то не правильный хэш выдает эта обработка? никто ее в деле не пробовал? или я что не так делаю?
21. Илья Асламов (7fortune) 04.08.12 01:44
Заработало!)там в реквизите пароль - длина 50 была, а у меня тестовая строчка больше размером была!Длину строки в реквизите увеличил и все заработало правильно! Спасибо автору за разработку!
22. Dmitry The Wing (wing) 28.02.13 10:32
Не работает обработка :(
Ввожу в нее строку, затем меняю символ, а хеш остается тем же ... понятно, что с символом, который не влияет на хеш надо угадать, но факт остается фактом - хеш не уникален для строки ...
23. Валерий Максимов (theshadowco) 06.05.13 18:27
(22) wing, вот не замысловатый код
Функция MD5Eng(КодируемаяСтрока)Экспорт

	оMD5 = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider");
	оEnc = Новый COMОбъект("System.Text.UTF8Encoding");
	оStr = Новый COMОбъект("System.Text.StringBuilder");

	// переводим в байтовый массив 
	Массив = оEnc.GetBytes_4(КодируемаяСтрока);
	
	// MD5
	Массив = оMD5.ComputeHash_2(Массив);
	
	// переведем обратно из байтового массива в строку
	КолЭлементовМассива = Массив.GetLength();
	Для Ит = 0 ПО КолЭлементовМассива - 1 Цикл 
	
		оStr.AppendFormat("{0:x02}", Массив.GetValue(Ит));
	
	КонецЦикла;
	
	оMD5 = NULL;
	оEnc = NULL;
	
	Возврат оStr.ToString();
	
КонецФункции // MD5Eng()

...Показать Скрыть
NewLifeMan; bajen; vet7777; MherArsh; dgolovanov; Arven; Жолтокнижниг; molodoi1sneg; jurgal1C; Dimon93dimon; Alex_Smolensky; OVladius; foka_1s; Andrey_ezhi; 1Cynep4eJIoBek; soci0pat; +16 Ответить 3
24. Вячеслав Клюев (slavik27) 20.06.13 07:46
спасибо очень интересно, попробую
25. Dmitry The Wing (wing) 15.07.13 04:58
(23) За пример со StringBuilder большое спасибо. Кодировку MD5 уже с год пользую именно таким способом, но числа в строку кодировал циклом на языке 1С (поиск в строке от 0 до f).

Только одна неточность: ToString - это не метод, а свойство, а значит скобки лесом.
26. Андрей Ершов (Andrey_ezhi) 20.02.14 16:31
(23)Спасибо, очень помогло! Для POST запроса надо было кодировать пароль по правилу md5(дата&пароль)
27. Женька Ture (ture) 14.07.15 15:03
(23) theshadowco, ты эту суёшь везде. Ну так знай, что на win2012 и выше это не работает.
28. Сергей Ожерельев (Поручик) 15.07.15 09:52
(27) Проснулся или из погреба выполз? Пост двухлетней давности.
29. Валерий Максимов (theshadowco) 10.08.15 18:57
(27) ture,
Во-первых "тыкать" неприлично, я с вами даже не знаком.
Во-вторых я данный метод на 8.1-8.2 использую много лет, включая и последние версии ОС от MS. Может поделитесь описанием ошибки из-за которой вы решили, что метод на данный момент использовать не стоит?
30. Михаил Максимов (МихаилМ) 10.08.15 23:39
начиная с версии 1с8 3.5.. реализована поддержка MD5

http://1c-programmer-blog.ru/programmirovanie/md5-v-1s.html
31. Валерий Максимов (theshadowco) 11.08.15 06:19
(30) МихаилМ, для 8.3 все понятно и известно (при том не в 8.3.5, а ранее).
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа