В современной разработке на платформе 1С часто возникает задача интеграции с внешними веб-сервисами, платежными шлюзами или API социальных сетей. Одной из стандартных процедур аутентификации в таких системах является использование алгоритма HMAC-SHA512. Это механизм вычисления кода аутентификации сообщений с использованием криптографической хеш-функции в сочетании с секретным ключом. В отличие от обычного хеширования, HMAC позволяет не только проверить целостность данных, но и подтвердить, что они были отправлены владельцем секретного ключа.
Рассмотрим подробно, как реализовать этот алгоритм в среде 1С, проанализируем возможные проблемы с кодировками и разберем способы преобразования полученного результата в читаемый формат (Base64 или Hex).
Если ваша информационная база работает под управлением операционной системы Windows, наиболее гибким способом будет обращение к библиотекам .NET через механизм COM-соединения. Для этого нам потребуются объекты System.Security.Cryptography.HMACSHA512 и System.Text.UTF8Encoding.
Разберем процесс по шагам:
Посмотрим на пример реализации кода:
// Подготовка строк
ТекстДляХеширования = "ДанныеДляПодписи";
СекретныйКлюч = "МойСекретныйКлюч";
// Инициализация объектов .NET через COM
Кодировка = Новый COMОбъект("System.Text.UTF8Encoding");
КриптоHMAC = Новый COMОбъект("System.Security.Cryptography.HMACSHA512");
// Установка ключа (преобразуем строку в массив байт)
КриптоHMAC.Key = Кодировка.GetBytes_4(СекретныйКлюч);
// Вычисление хеша
МассивБайтХеша = КриптоHMAC.ComputeHash_2(Кодировка.GetBytes_4(ТекстДляХеширования)).Выгрузить();
Важный нюанс: метод ComputeHash_2 возвращает типизированный массив .NET. Чтобы работать с ним в 1С, мы используем метод Выгрузить(), который превращает его в стандартный массив 1С, содержащий числа (значения байтов от 0 до 255).
После получения массива чисел нам необходимо представить его в виде строки, пригодной для передачи в HTTP-заголовках или теле запроса. Чаще всего требуется либо кодировка Base64, либо шестнадцатеричное представление (Hex), которое аналогично результату функции hash_hmac в PHP.
Рассмотрим, как правильно преобразовать массив с использованием объекта БуферДвоичныхДанных, что является наиболее современным и быстрым способом в 1С:
// Создаем буфер нужного размера
Буфер = Новый БуферДвоичныхДанных(МассивБайтХеша.Количество());
Счетчик = 0;
// Заполняем буфер значениями из массива
Для Каждого Байт Из МассивБайтХеша Цикл
Буфер.Установить(Счетчик, Байт);
Счетчик = Счетчик + 1;
КонецЦикла;
// Получаем двоичные данные из буфера
ДвоичныеДанныеХеша = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(Буфер);
// Вариант А: Получение строки Base64
СтрокаBase64 = Base64Строка(ДвоичныеДанныеХеша);
// Убираем переносы строк, если они добавились платформой
СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ПС, "");
СтрокаBase64 = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
// Вариант Б: Получение шестнадцатеричной строки (Hex)
// В новых версиях платформы можно использовать:
СтрокаHex = НРег(СтрЗаменить(Строка(ДвоичныеДанныеХеша), " ", ""));
Проанализируем ситуацию, когда необходимо соответствовать PHP-функции hash_hmac("sha512", $data, $secret). По умолчанию PHP возвращает именно нижний регистр Hex-строки. Именно поэтому в коде выше мы используем НРег для приведения результата к нижнему регистру.
Если вы используете современную версию платформы 1С, крайне рекомендуется отказаться от COM-объектов в пользу встроенного объекта МенеджерКриптографии. Это обеспечит кроссплатформенность вашего кода (работу на Linux) и повысит стабильность системы.
Выясним, как это реализовать:
// Подготовка данных
ТекстДляХеширования = "ДанныеДляПодписи";
КлючСтрока = "МойСекретныйКлюч";
// Преобразуем строки в ДвоичныеДанные
ДанныеДляОбработки = ПолучитьДвоичныеДанныеИзСтроки(ТекстДляХеширования, КодировкаТекста.UTF8);
КлючДанные = ПолучитьДвоичныеДанныеИзСтроки(КлючСтрока, КодировкаТекста.UTF8);
// Создаем менеджер криптографии
// Обратите внимание: для HMAC в 1С используется специальный подход
Менеджер = Новый МенеджерКриптографии("");
ХешСумма = Менеджер.ПолучитьHMAC(ДанныеДляОбработки, КлючДанные, АлгоритмХеширования.SHA512);
// Результат ХешСумма уже является объектом ДвоичныеДанные
РезультатHex = НРег(СтрЗаменить(Строка(ХешСумма), " ", ""));
Этот способ является наиболее предпочтительным, так как он не зависит от установленного в системе .NET Framework и работает значительно быстрее за счет отсутствия накладных расходов на COM-взаимодействие.
Разберем основные причины, по которым хеш в 1С может не совпадать с хешем, полученным в PHP или других системах:
UTF-8. Если одна сторона использует Windows-1251, а другая UTF-8, хеш-суммы будут абсолютно разными. Всегда явно указывайте кодировку UTF8Encoding или КодировкаТекста.UTF8.СокрЛП() для обработки входных строк.a-f против A-F). Используйте ВРег() или НРег() для обеспечения единообразия.Подводя итог, можно сказать, что реализация HMAC-SHA512 в 1С пройдена путь от сложных манипуляций с внешними компонентами до элегантного использования встроенных методов МенеджерКриптографии. При выборе метода всегда ориентируйтесь на версию вашей платформы и требования к кроссплатформенности решения.