Для получения HMAC в функцию передается первым параметром — ключ K
. Второй параметр — сообщение text
, которое будет передаваться отправителем и подлинность которого будет проверяться получателем. Третим параметром тип хеш-функции Hash
(CRC32, MD5, SHA1, SHA256) . После чего на выходе мы получаем код аутентификации.
// Функция - HMAC
//
// Параметры: 1
// K - ключ в шестнадцатеричном виде - Строка
// text - текстовое сообщение - Строка
// Hash - Hash function (CRC32, MD5, SHA1, SHA256) - Строка
// Возвращаемое значение:
// строка HMAC - Строка
Функция HMAC(Знач K, Знач text, Знач Hash)
Перем kResult;
Перем К0;
//Если длина ключа K больше размера блока, то к ключу K применяем хэш-функцию
Если СтрДлина(K)>128 Тогда
K = SHA1(K,Hash);
КонецЕсли;
//1 Дополняем ключ K нулевыми байтами до размера блока. Размер блока хэш-функции SHA-1 равен 64 байтам.
StringSHA1 = Лев(K,128);
Для к = СтрДлина(K) По 128 Цикл
StringSHA1 = StringSHA1 + "0";
КонецЦикла;
К0 = StringSHA1;
//2 Выполняем операцию «побитовое исключающее ИЛИ» c константой 0x36.
b = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ("36"));
к = 1;
Пока к < 128 Цикл
a = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ(Сред(StringSHA1,к,2)));
с = XOR(a,b);
StringSHA1 = Лев(StringSHA1,к-1)+с+Прав(StringSHA1, 128-к);
к = к + 2;
КонецЦикла;
StringSHA1 = Лев(StringSHA1,128);
//3 Выполняем склейку исходного сообщения со строкой, полученной на шаге 2.
Для к = 1 По СтрДлина(text) Цикл
StringSHA1 = StringSHA1 + ПреобразоватьДесятичнуюСИВHex(КодСимвола(Сред(text,к,1)));
КонецЦикла;
//4 Применим хэш-функцию SHA-1 к строке, полученной на прошлом шаге.
StringSHA1 = SHA1(StringSHA1,Hash);
kResult = StringSHA1;
//5 Выполним операцию «побитовое исключающее ИЛИ» c константой 0x5c.
StringSHA1 = К0;
b = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ("5c"));
к = 1;
Пока к < 128 Цикл
a = ПреобразоватьЧислоВДвоичнуюСИ(ПреобразоватьHexВДесятичнуюСИ(Сред(StringSHA1,к,2)));
с = XOR(a,b);
StringSHA1 = Лев(StringSHA1,к-1)+с+Прав(StringSHA1, 128-к);
к = к + 2;
КонецЦикла;
StringSHA1 = Лев(StringSHA1,128);
//6 Склейка строки, полученной на шаге 4, со строкой, полученной на шаге 5.
StringSHA1 = StringSHA1 + kResult;
//7 Применим хэш-функцию SHA-1 к строке, полученной на прошлом шаге.
StringSHA1 = SHA1(StringSHA1,Hash);
Возврат StringSHA1;
КонецФункции
Функция SHA1(Знач nString, Hash)
Хеширование = Новый ХешированиеДанных(ХешФункция[Hash]);
ТипhexBinary = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "hexBinary");
ДвоичныеДанные = ФабрикаXDTO.Создать(ТипhexBinary,nString);
Хеширование.Добавить(ДвоичныеДанные.Значение);
sign = Хеширование.ХешСумма;
sign = СтрЗаменить(НРЕГ(sign), " ", "");
Возврат СтрЗаменить(НРЕГ(sign), " ", "");
КонецФункции
Функция ПреобразоватьДесятичнуюСИВHex(Знач int)
Если int < 256 Тогда
Возврат Прав("00" + ПреобразоватьДесятичнуюСИВОднобайтовыйHex(int),2);
Иначе
Возврат Прав("0000" + ПреобразоватьДесятичнуюСИВДвухбайтовыйHex(int),4);
КонецЕсли;
КонецФункции
Функция ПреобразоватьHexВДесятичнуюСИ(Знач hex)
simbol = СтрДлина(hex) - 1;
dec = 0;
i = 1;
Пока simbol >= 0 Цикл
simbolHex = Сред(hex, i, 1);
Res = Найти("0123456789abcdef", simbolHex) - 1;
dec = dec + Res * Pow(16, simbol);
simbol = simbol - 1;
i = i + 1;
КонецЦикла;
Возврат dec;
КонецФункции
Функция ПреобразоватьЧислоВДвоичнуюСИ(Знач int, rBit = 8)
b = "";
Для k = 1 По rBit Цикл
m = pow(2, rBit - k);
bit = Цел(int / m);
int = int - m * bit;
b = b + bit;
КонецЦикла;
Возврат b;
КонецФункции
Функция XOR(a, b)
res = 0;
s = 1;
к = Мин(СтрДлина(a), СтрДлина(b));
Пока к > 0 Цикл
a1 = Сред(a,к,1);
b1 = Сред(b,к,1);
res = res + s * ?(a1=b1,0,Макс(a1,b1));
s = s*2;
к = к-1;
КонецЦикла;
Возврат ПреобразоватьДесятичнуюСИВHex(res);
КонецФункции
Функция ПреобразоватьДесятичнуюСИВДвухбайтовыйHex(Знач int)
BinaryData = ПреобразоватьЧислоВДвоичнуюСИ(int, 11);
BinaryData = "110" + Лев(BinaryData,5) + "10" + Прав(BinaryData, 6);
DecimalData = ПолучитьДесятичноеЧислоИзДвоичного(BinaryData);
HexData = ПреобразоватьДесятичнуюСИВОднобайтовыйHex(DecimalData);
Возврат HexData;
КонецФункции
Функция ПолучитьДесятичноеЧислоИзДвоичного(b)
res = 0;
s = 1;
к = СтрДлина(b);
Пока к > 0 Цикл
bit = Сред(b,к,1);
res = res + s * bit;
s = s*2;
к = к-1;
КонецЦикла;
Возврат res;
КонецФункции
Функция ПреобразоватьДесятичнуюСИВОднобайтовыйHex(Знач int)
hex = "";
Пока int <> 0 Цикл
p = int % 16;
hex = Сред("0123456789abcdef", p + 1, 1) + hex;
int = Цел(int / 16);
КонецЦикла;
Возврат hex;
КонецФункции
Описпние алгоритма можно посмотреть в Википедии (https://ru.wikipedia.org/wiki/HMAC)
Битовые операции (//infostart.ru/public/99739/)
Преобразование dec to hex и hex to dec https://ru.wikipedia.org/wiki/Позиционная_система_счисления
Представление кириллицы в UTF-8 http://i.voenmeh.ru/kafi5/Kam.loc/inform/UTF-8.htm