Как в 1С сформировать хеш HMAC-SHA1 с секретным ключом для интеграции с веб-сервисом

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С со сторонними веб-сервисами, интернет-магазинами или платежными шлюзами часто требуется сформировать цифровую подпись запроса (хеш по алгоритму HMAC-SHA1) с использованием секретного ключа (Secret Key). Однако при попытке использовать типовой объект ХешированиеДанных результат расчета не совпадает с данными внешнего сервиса или онлайн-генераторов.

Разберем причины возникновения этой проблемы и рассмотрим рабочие способы вычисления правильного значения HMAC-SHA1 в среде 1С:Предприятие.

Выясним причину: почему ХешированиеДанных возвращает другой результат

Проанализируем распространенную ошибку. Разработчики часто пытаются передать ключ и строку последовательно через метод Добавить() объекта ХешированиеДанных:


ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.SHA1);
ХешированиеДанных.Добавить("superkey");
ХешированиеДанных.Добавить("/auth/token/merchants");
ХешДанных = ХешированиеДанных.ХешСумма;

В этом случае платформа 1С выполняет простое последовательное вычисление контрольной суммы от конкатенации двух строк: SHA1("superkey" + "/auth/token/merchants").

Алгоритм HMAC (Hash-based Message Authentication Code) устроен совершенно иначе. Согласно стандарту RFC 2104, он использует двухэтапное хеширование с модификацией ключа специальными байтовыми масками (ipad = 0x36 и opad = 0x5C) по формуле:

HMAC(K, m) = H((K XOR opad) || H((K XOR ipad) || m))

Следовательно, стандартное склеивание строк через ХешированиеДанных.Добавить() принципиально не может дать значение HMAC.

Также обратим внимание на типичные ошибки при подготовке исходных данных:

  1. Лишние кавычки при JSON-сериализации: если применять функцию ЗаписатьJSON() к обычной строке, она автоматически оборачивается в экранированные двойные кавычки (например, "\"/auth/...\""), что полностью искажает итоговый хеш.
  2. Кодировка и служебные символы: запись во временные файлы через ЗаписьТекста может добавлять символы перевода строк (CRLF) или метку порядка байтов (BOM), что меняет бинарный поток данных.

Способ 1. Расчет HMAC-SHA1 через COM-объект .NET Framework (для Windows)

Если сервер 1С или клиентское рабочее место работает под управлением ОС Windows с установленной средой .NET Framework, мы можем использовать встроенные классы криптографии через интерфейс COM. Это наиболее компактное решение для операционных систем Windows.

Посмотрим на пример реализации функции:


Функция ЗашифроватьHMAC_SHA1(Знач СтрокаСообщения, Знач СекретныйКлюч) Экспорт

    // Создаем COM-объекты для работы с кодировкой UTF-8 и алгоритмом HMAC-SHA1
    ОбъектКодировки = Новый COMОбъект("System.Text.UTF8Encoding");
    ОбъектКриптографии = Новый COMОбъект("System.Security.Cryptography.HMACSHA1");
    
    // Передаем секретный ключ в байтовом виде
    ОбъектКриптографии.Key = ОбъектКодировки.GetBytes_4(СекретныйКлюч);
    
    // Получаем массив байтов сообщения и вычисляем HMAC-хеш
    БайтыСообщения = ОбъектКодировки.GetBytes_4(СтрокаСообщения);
    ХешБайты = ОбъектКриптографии.ComputeHash_2(БайтыСообщения).Выгрузить();
    
    // Преобразуем байтовый массив в шестнадцатеричную (HEX) строку
    ИтоговыйХеш = "";
    Для Каждого Байт Из ХешБайты Цикл
        СимволHex = DecToHex(Байт);
        ИтоговыйХеш = ИтоговыйХеш + ?(СтрДлина(СимволHex) = 2, СимволHex, "0" + СимволHex);
    КонецЦикла;
    
    Возврат НРег(ИтоговыйХеш);

КонецФункции

Функция DecToHex(Знач Число)
    
    База = 16;
    Результат = "";
    СимволыHex = "0123456789abcdef";
    
    Пока Число > 0 Цикл
        Остаток = Число % База;
        Результат = Сред(СимволыHex, Остаток + 1, 1) + Результат;
        Число = Цел(Число / База);
    КонецЦикла;
    
    Возврат ?(Результат = "", "00", Результат);
    
КонецФункции

Разберем особенности работы данного кода:

  1. Перегрузка методов в COM: из-за особенностей взаимодействия 1С с COM-объектами .NET перегруженные методы вызываются с суффиксами (например, GetBytes_4 и ComputeHash_2).
  2. Результат выполнения: при передаче параметров СекретныйКлюч = "superkey" и СтрокаСообщения = "/auth/token/merchants" функция вернет точное значение 62e37f6dc60083ba969f06ec2276a8682bec227b.

Способ 2. Кроссплатформенная реализация алгоритма на встроенном языке 1С

Если сервер 1С:Предприятие работает под управлением Linux или в режиме веб-клиента, использование COM-объектов невозможно. В современных версиях платформы 1С:Предприятие (начиная с 8.3.10) задачу можно решить штатным встроенным языком с помощью объектов БуферДвоичныхДанных и ДвоичныеДанные.

Рассмотрим пошаговый алгоритм:

  1. Преобразуем строку ключа и сообщение в ДвоичныеДанные в кодировке UTF-8 без BOM с помощью метода ПолучитьДвоичныеДанныеИзСтроки().
  2. Приводим ключ к длине блока алгоритма SHA-1 (64 байта): если длина ключа больше 64 байт, хешируем его через ХешированиеДанных(ХешФункция.SHA1); если меньше — дополняем нулевыми байтами справа до 64 байт.
  3. Создаем два буфера размером 64 байта: внутреннюю маску ipad (заполненную байтами 0x36) и внешнюю маску opad (заполненную байтами 0x5C).
  4. Выполняем операцию XOR между подготовленным ключом и масками с помощью метода буфера ЗаписатьПобитовоеИсключительноеИли(), получая блоки K_ipad и K_opad.
  5. Вычисляем внутренний хеш SHA-1 от объединения K_ipad и исходного сообщения.
  6. Вычисляем внешний итоговый хеш SHA-1 от объединения K_opad и полученного внутреннего хеша.
  7. Переводим итоговые двоичные данные в HEX-строку функцией ПолучитьHexСтрокуИзДвоичныхДанных() или в Base64 через Base64Строка() в зависимости от требований стороннего сервиса.

Такой подход обеспечивает полную независимость от операционной системы и корректно работает на любых конфигурациях и платформах 1С.

← На главную