Как в 1С правильно закодировать Hex-строку хеша в Base64 длиной 44 символа?

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

При интеграции 1С с внешними веб-сервисами, платежными шлюзами или REST API разработчики часто сталкиваются с необходимостью формирования цифровых подписей (хешей, HMAC или дайджестов сообщений). Нередко документация стороннего сервиса требует передать 32-байтный хеш (например, SHA-256), закодированный в формат Base64. В таких спецификациях длина результирующей строки составляет ровно 44 символа.

Однако при попытке повторить пример из Python или документации в 1С разработчики получают строку длиной 88 символов вместо ожидаемых 44. Выясним причину этой ошибки и разберем правильные способы решения задачи на платформе 1С:Предприятие.

Проанализируем суть проблемы и причину различия в размере

Посмотрим на исходный код, который приводит к некорректной длине:


Подпись = "11832f9b12b16c8dee2f17752ed9939133f59c1f71c8ec2d64e24919dc985a83";
ДвДанные = ПолучитьДвоичныеДанныеИзСтроки(Подпись, КодировкаТекста.UTF8, Ложь);
Encoded = Base64Строка(ДвДанные); // Получается 88 символов

Разберем, почему так происходит:

  1. Строка переменной Подпись состоит из 64 символов. Это шестнадцатеричное (Hex) представление 32 байт информации (каждые 2 hex-символа соответствуют 1 байту: 64 / 2 = 32).
  2. Метод ПолучитьДвоичныеДанныеИзСтроки интерпретирует эту строку как обычный текст. Каждый символ латиницы или цифры кодируется в кодировке UTF-8 ровно одним байтом. В итоге в объекте ДвоичныеДанные оказывается буфер размером не 32, а 64 байта.
  3. Алгоритм Base64 преобразует каждые 3 байта исходных данных в 4 символа текста. Для 64 байт получается (64 / 3) * 4 с выравниванием — ровно 88 символов.
  4. В Python-коде переменная digest представляет собой исходный массив байт (32 байта), а не текстовую шестнадцатеричную строку. При кодировании 32 байт в Base64 получается: (32 / 3) * 4 с выравниванием — ровно 44 символа (включая символ = на конце).

Основное решение: использование метода ПолучитьДвоичныеДанныеИзHexСтроки

Чтобы преобразовать шестнадцатеричную строку в исходные двоичные данные, необходимо использовать специализированный метод платформы, который считывает пары символов как байты, а не как текст UTF-8.

Заменим вызов функции и посмотрим на правильный код:


Подпись = "11832f9b12b16c8dee2f17752ed9939133f59c1f71c8ec2d64e24919dc985a83";

// Корректное преобразование Hex в ДвоичныеДанные (буфер 32 байта)
ДвДанные = ПолучитьДвоичныеДанныеИзHexСтроки(Подпись);

// Получаем строку Base64 длиной ровно 44 символа
Encoded = Base64Строка(ДвДанные);

При таком подходе шестнадцатеричная строка будет упакована в ровно 32 байта, а функция Base64Строка() выдаст ожидаемый результат в 44 символа, полностью совпадающий с результатом работы Python или других языков программирования.

Ограничения и нюансы работы с Hex-методами в 1С

При использовании метода ПолучитьДвоичныеДанныеИзHexСтроки важно учитывать следующие технические особенности платформы:

  1. Версия платформы: Штатные методы работы с шестнадцатеричными строками (ПолучитьДвоичныеДанныеИзHexСтроки и ПолучитьHexСтрокуИзДвоичныхДанных) появились начиная с версии платформы 8.3.10.
  2. Строгая валидация входящей строки: Платформа жестко проверяет формат строки. Длина строки обязана быть четной, а в составе допустимы только шестнадцатеричные цифры (0-9, a-f, A-F). Если во входной строке окажутся случайные пробелы, табуляции или символы перевода строк (\r\n), метод выбросит исключение времени выполнения.
  3. Очистка данных перед вызовом: Перед передачей строки в метод рекомендуется гарантированно удалить непечатные символы с помощью СокрЛП и при необходимости СтрЗаменить.

Альтернативный вариант: расчет хеша напрямую без промежуточного Hex

Часто шестнадцатеричная строка появляется в коде только потому, что разработчик сначала вычисляет хеш и переводит его в читаемый вид. Если дайджест рассчитывается непосредственно в 1С штатными средствами, промежуточный шаг с переводом в Hex-строку является лишним.

Рассмотрим, как оптимизировать этот процесс:


Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить("ТекстДляПодписи");

// Свойство ХешСумма уже возвращает ДвоичныеДанные (32 байта)
ДвоичныеДанныеХеша = Хеширование.ХешСумма;

// Сразу получаем Base64 длиной 44 символа
Encoded = Base64Строка(ДвоичныеДанныеХеша);

Такой подход избавляет от двойной конвертации типов и работает быстрее.

Особенности для веб-интеграций: Base64URL

Проанализируем еще одну частую проблему при работе с API. Если подпись или токен формируются для передачи через URL-параметры или HTTP-заголовки (например, в спецификации JWT), принимающий сервис часто требует формат Base64URL вместо классического Base64.

Функция Base64Строка() платформы 1С всегда формирует классический Base64. Чтобы привести результат к стандарту Base64URL, выполним нормализацию строки по шагам:


// Заменяем символы, недопустимые в URL, и удаляем дополнение выравнивания
СтрокаBase64URL = СтрЗаменить(Encoded, "+", "-");
СтрокаBase64URL = СтрЗаменить(СтрокаBase64URL, "/", "_");
СтрокаBase64URL = СтрЗаменить(СтрокаBase64URL, "=", "");

Эти правила позволят корректно формировать подписи для любых внешних систем и сервисов аутентификации.

← На главную