Как реализовать хеширование данных HMAC-SHA256 в 1С 7.7 для работы с API

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции 1С 7.7 с современными веб-сервисами (SMS-шлюзы, банковские API, маркетплейсы) программисты часто сталкиваются с требованием подписывать запросы алгоритмом HMAC-SHA256. Платформа 1С:Предприятие 7.7, созданная задолго до повсеместного внедрения таких стандартов, не имеет встроенных функций для криптографии этого типа. Рассмотрим подробнее, какими способами можно решить эту задачу, используя доступные системные ресурсы и внешние компоненты.

Причина сложности: Кодировки и алгоритмы

Основная проблема заключается в том, что 1С 7.7 работает в кодировке ANSI (Windows-1251), тогда как большинство современных API требуют, чтобы строка перед хешированием была преобразована в UTF-8. Кроме того, сам алгоритм SHA256 гораздо сложнее старых MD5 или SHA1, и его реализация на чистом встроенном языке 1С была бы крайне медленной. Выясним, как обойти эти ограничения.

Решение 1: Использование классов .NET через внешнюю компоненту

Проанализируем наиболее надежный и производительный метод — использование библиотек .NET Framework, которые уже присутствуют в любой современной ОС Windows. Для того чтобы «подружить» 1С 7.7 и .NET, часто используется внешняя компонента NetObjectToIDispatch. Она позволяет обращаться к мощным криптографическим классам напрямую из кода 1С.

Разберем по шагам пример функции, которая вычисляет HMAC-SHA256:


Функция ВычислитьHMAC(КлючAPI, СтрокаДанных)
    // Создаем объект для связи с .NET
    Врап = СоздатьОбъект("NetObjectToIDispatch45");
    Врап.УстЭтоСемерка();
    
    // Получаем доступ к кодировке UTF8
    Encoding = Врап.ПолучитьТип("System.Text.Encoding").UTF8; 
    
    // Преобразуем ключ и сообщение в байтовые массивы UTF-8
    КлючБайты = Encoding.GetBytes(КлючAPI); 
    СообщениеБайты = Encoding.GetBytes(СтрокаДанных); 
    
    // Создаем объект HMACSHA256 с использованием ключа
    HMAC = Врап.СоздатьОбъект("System.Security.Cryptography.HMACSHA256", КлючБайты); 
    
    // Вычисляем хеш
    ХешБайты = HMAC.ComputeHash(СообщениеБайты); 
    
    // Преобразуем результат в шестнадцатеричную строку (hex)
    BitConverter = Врап.ПолучитьТип("System.BitConverter");
    РезультатHex = Нрег(СтрЗаменить(BitConverter.ToString(ХешБайты), "-", ""));
    
    Возврат РезультатHex;            
КонецФункции

В этом примере объект System.Security.Cryptography.HMACSHA256 берет на себя всю тяжелую математическую работу. Использование BitConverter позволяет быстро перевести массив байтов в строковое представление, которое обычно и требуется для передачи в заголовках HTTP-запроса.

Решение 2: Использование MSScriptControl и JavaScript

Если нет возможности регистрировать специализированные компоненты типа NetObjectToIDispatch, можно воспользоваться стандартным системным компонентом MSScriptControl.ScriptControl. Этот объект позволяет исполнять код на языке JScript (аналог JavaScript от Microsoft). Посмотрим на пример реализации:

  1. Подготовка библиотеки: Нам понадобится текст реализации алгоритма SHA256 на JavaScript. Его можно сохранить в текстовый файл или загрузить в макет конфигурации.
  2. Инициализация скрипта: Создаем объект и загружаем в него код библиотеки.
  3. Вызов функции: Передаем данные из 1С в JavaScript и получаем результат обратно.

Рассмотрим пример кода в 1С:


Процедура ПолучитьПодпись()
    // Инициализируем ScriptControl
    ScrptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl");
    ScrptCtrl.Language = "JScript"; 
    
    // Здесь должен быть текст JS-библиотеки CryptoJS или аналогичной
    ТекстСкрипта = "// ... текст библиотеки SHA256 ...";
    ScrptCtrl.AddCode(ТекстСкрипта);
    
    // Формируем данные для хеширования
    Данные = "messagessinglesms{""target"": ""BAMBOO"", ""text"": ""Hello""}";
    СекретныйКлюч = "MyApiKey123";
    
    // Вызываем функцию хеширования из JS
    // Предположим, в библиотеке есть функция CryptoJS.HmacSHA256
    Подпись = ScrptCtrl.Eval("CryptoJS.HmacSHA256('" + Данные + "', '" + СекретныйКлюч + "').toString(CryptoJS.enc.Hex)");
    
    Сообщить("Подпись: " + Подпись);
КонецПроцедуры

Важный нюанс: Стандартный MSScriptControl работает с движком JScript, который соответствует старым стандартам. При выборе JS-библиотеки убедитесь, что она совместима со старыми браузерами (Internet Explorer 8 и ниже), иначе возникнут ошибки синтаксиса при добавлении кода через AddCode.

Решение 3: Вызов внешних утилит (PowerShell или консольные скрипты)

В ситуациях, когда работа с COM-объектами затруднена (например, из-за настроек безопасности или разрядности системы), можно прибегнуть к вызову внешнего приложения. В современных версиях Windows (начиная с 7) встроен PowerShell, который также имеет доступ к .NET Framework.

Посмотрим, как можно вычислить хеш через PowerShell, не выходя из 1С:


// Пример вызова через командную строку
Команда = "powershell -command ""[Reflection.Assembly]::LoadWithPartialName('System.Security'); " +
          "$hasher = New-Object System.Security.Cryptography.HMACSHA256; " +
          "$hasher.Key = [Text.Encoding]::UTF8.GetBytes('" + КлючAPI + "'); " +
          "$hash = $hasher.ComputeHash([Text.Encoding]::UTF8.GetBytes('" + СтрокаДанных + "')); " +
          "$hash | foreach { $_.ToString('x2') } | Write-Host""";

// Выполняем команду и перенаправляем вывод в файл или считываем через WScript.Shell
ВкШелл = СоздатьОбъект("WScript.Shell");
Выполнение = ВкШелл.Exec(Команда);
Результат = Выполнение.StdOut.ReadAll();

Этот способ хорош тем, что он не требует регистрации никаких дополнительных DLL в системе, так как PowerShell является частью ОС.

Работа с UTF-8 в 1С 7.7 без внешних средств

Рассмотрим ситуацию, когда нам нужно подготовить строку в UTF-8 для передачи в MSScriptControl или внешнюю утилиту. В 1С 7.7 нет встроенной функции К_UTF8(), но мы можем воспользоваться объектом ADODB.Stream. Проанализируем пример функции конвертации:


Функция ANSI_To_UTF8(Стр)
    Стрим = СоздатьОбъект("ADODB.Stream");
    Стрим.Type = 2; // Text
    Стрим.Charset = "windows-1251";
    Стрим.Open();
    Стрим.WriteText(Стр);
    
    Стрим.Position = 0;
    Стрим.Charset = "utf-8";
    Результат = Стрим.ReadText();
    Стрим.Close();
    
    Возврат Результат;
КонецФункции

Подведем итоги

Для реализации HMAC-SHA256 в 1С 7.7 наиболее предпочтительным является Решение 1 (через .NET компоненту), так как оно обеспечивает максимальную скорость и корректную обработку типов данных. Если же вы ограничены в правах на установку компонент, используйте Решение 2 с проверенной JavaScript-библиотекой. Всегда уделяйте внимание кодировке: несоответствие ANSI и UTF-8 — самая частая причина того, что сервер API возвращает ошибку "Invalid Signature".

← На главную