При интеграции 1С с внешними веб-сервисами, платежными шлюзами или REST API разработчики часто сталкиваются с необходимостью формирования цифровых подписей (хешей, HMAC или дайджестов сообщений). Нередко документация стороннего сервиса требует передать 32-байтный хеш (например, SHA-256), закодированный в формат Base64. В таких спецификациях длина результирующей строки составляет ровно 44 символа.
Однако при попытке повторить пример из Python или документации в 1С разработчики получают строку длиной 88 символов вместо ожидаемых 44. Выясним причину этой ошибки и разберем правильные способы решения задачи на платформе 1С:Предприятие.
Посмотрим на исходный код, который приводит к некорректной длине:
Подпись = "11832f9b12b16c8dee2f17752ed9939133f59c1f71c8ec2d64e24919dc985a83";
ДвДанные = ПолучитьДвоичныеДанныеИзСтроки(Подпись, КодировкаТекста.UTF8, Ложь);
Encoded = Base64Строка(ДвДанные); // Получается 88 символов
Разберем, почему так происходит:
Подпись состоит из 64 символов. Это шестнадцатеричное (Hex) представление 32 байт информации (каждые 2 hex-символа соответствуют 1 байту: 64 / 2 = 32).ПолучитьДвоичныеДанныеИзСтроки интерпретирует эту строку как обычный текст. Каждый символ латиницы или цифры кодируется в кодировке UTF-8 ровно одним байтом. В итоге в объекте ДвоичныеДанные оказывается буфер размером не 32, а 64 байта.(64 / 3) * 4 с выравниванием — ровно 88 символов.digest представляет собой исходный массив байт (32 байта), а не текстовую шестнадцатеричную строку. При кодировании 32 байт в Base64 получается: (32 / 3) * 4 с выравниванием — ровно 44 символа (включая символ = на конце).Чтобы преобразовать шестнадцатеричную строку в исходные двоичные данные, необходимо использовать специализированный метод платформы, который считывает пары символов как байты, а не как текст UTF-8.
Заменим вызов функции и посмотрим на правильный код:
Подпись = "11832f9b12b16c8dee2f17752ed9939133f59c1f71c8ec2d64e24919dc985a83";
// Корректное преобразование Hex в ДвоичныеДанные (буфер 32 байта)
ДвДанные = ПолучитьДвоичныеДанныеИзHexСтроки(Подпись);
// Получаем строку Base64 длиной ровно 44 символа
Encoded = Base64Строка(ДвДанные);
При таком подходе шестнадцатеричная строка будет упакована в ровно 32 байта, а функция Base64Строка() выдаст ожидаемый результат в 44 символа, полностью совпадающий с результатом работы Python или других языков программирования.
При использовании метода ПолучитьДвоичныеДанныеИзHexСтроки важно учитывать следующие технические особенности платформы:
ПолучитьДвоичныеДанныеИзHexСтроки и ПолучитьHexСтрокуИзДвоичныхДанных) появились начиная с версии платформы 8.3.10.0-9, a-f, A-F). Если во входной строке окажутся случайные пробелы, табуляции или символы перевода строк (\r\n), метод выбросит исключение времени выполнения.СокрЛП и при необходимости СтрЗаменить.Часто шестнадцатеричная строка появляется в коде только потому, что разработчик сначала вычисляет хеш и переводит его в читаемый вид. Если дайджест рассчитывается непосредственно в 1С штатными средствами, промежуточный шаг с переводом в Hex-строку является лишним.
Рассмотрим, как оптимизировать этот процесс:
Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256);
Хеширование.Добавить("ТекстДляПодписи");
// Свойство ХешСумма уже возвращает ДвоичныеДанные (32 байта)
ДвоичныеДанныеХеша = Хеширование.ХешСумма;
// Сразу получаем Base64 длиной 44 символа
Encoded = Base64Строка(ДвоичныеДанныеХеша);
Такой подход избавляет от двойной конвертации типов и работает быстрее.
Проанализируем еще одну частую проблему при работе с API. Если подпись или токен формируются для передачи через URL-параметры или HTTP-заголовки (например, в спецификации JWT), принимающий сервис часто требует формат Base64URL вместо классического Base64.
Функция Base64Строка() платформы 1С всегда формирует классический Base64. Чтобы привести результат к стандарту Base64URL, выполним нормализацию строки по шагам:
// Заменяем символы, недопустимые в URL, и удаляем дополнение выравнивания
СтрокаBase64URL = СтрЗаменить(Encoded, "+", "-");
СтрокаBase64URL = СтрЗаменить(СтрокаBase64URL, "/", "_");
СтрокаBase64URL = СтрЗаменить(СтрокаBase64URL, "=", "");
Эти правила позволят корректно формировать подписи для любых внешних систем и сервисов аутентификации.