Как получить хэш файла или строки на клиенте в 1С без передачи данных на сервер

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

В процессе разработки часто возникает задача проверки целостности файлов или идентификации данных по их контрольной сумме. Стандартный объект платформы 1С ХешированиеДанных доступен только на стороне сервера. Это создает определенные трудности: если файл находится на компьютере пользователя, нам приходится передавать его целиком на сервер только для того, чтобы вычислить короткую строку хэша. Если файлы имеют большой объем, это перегружает сеть и замедляет работу системы.

В данной статье мы разберем несколько эффективных способов получения хэша непосредственно на клиентском месте, проанализируем их применимость для различных типов клиентов (Тонкий, Веб) и операционных систем.

Способ 1. Использование системной утилиты CertUtil через COM-объект (только для Windows)

Для пользователей, работающих в Тонком клиенте под управлением ОС Windows, самым быстрым и простым способом будет использование встроенной системной утилиты CertUtil. Мы можем запустить ее через WScript.Shell, получить результат выполнения и прочитать его прямо в коде 1С.

Проанализируем ситуацию: нам нужно вызвать командную строку, выполнить расчет и забрать поток стандартного вывода StdOut. Рассмотрим пример кода, который реализует этот механизм:


// Создаем объект для взаимодействия с оболочкой Windows
Выполнитель = Новый COMОбъект("WScript.Shell");

// Формируем команду. Используем CertUtil с параметром -hashfile
// Добавляем фильтр findstr, чтобы оставить только саму строку хэша
ПутьКФайлу = "C:\tools\rdp.exe";
Алгоритм = "MD5"; // Можно использовать SHA1, SHA256
Команда = "cmd /c CertUtil -hashfile " + ПутьКФайлу + " " + Алгоритм + " | findstr ^[0-9a-f]$";

// Выполняем команду и читаем результат
ПотокРезультата = Выполнитель.Exec(Команда);
Результат = ПотокРезультата.StdOut.ReadAll();

// Очищаем результат от лишних символов (перевод строки)
Результат = СокрЛП(СтрЗаменить(Результат, Символы.ПС, ""));
Результат = СтрЗаменить(Результат, Символы.ВК, "");

Сообщить("Хэш файла: " + Результат);

Важный нюанс: данный метод работает очень быстро, так как вычисления происходят на уровне оптимизированной системной утилиты. Однако он не применим в веб-клиенте и на мобильных устройствах, так как требует наличия COM-интерфейса и прав на запуск внешних приложений.

Способ 2. Математический расчет на языке 1С (через функции БСП)

Если нам необходимо обеспечить работу в Веб-клиенте или если использование COM-объектов запрещено политиками безопасности, мы можем прибегнуть к математическому расчету алгоритма хэширования непосредственно на встроенном языке 1С. В старых версиях «Библиотеки стандартных подсистем» (БСП) присутствовали функции для вычисления MD5. Для реализации низкоуровневых алгоритмов на чистом коде 1С подойдёт библиотека для работы с двоичными данными на клиентах 1С.

Рассмотрим подробнее: такие функции работают на основе преобразования строки в двоичные данные и последующего выполнения циклов логических операций (AND, OR, XOR, SHIFT). Пример обращения к подобной функции:


// Пример использования функции из состава старых версий БСП или самописных модулей
СтрокаДанных = "Пример текста для хеширования";
Хеш = СтроковыеФункцииКлиентСервер.ВычислитьХешСтрокиПоАлгоритмуMD5(СтрокаДанных);
Сообщить(Хеш);

Выясним причину ограничений этого метода:

  1. Производительность: встроенный язык 1С является интерпретируемым. Сложные математические расчеты в циклах (а MD5 требует их тысячи) выполняются значительно медленнее, чем в скомпилированном C++ коде.
  2. Объем данных: данный метод хорошо подходит для коротких строк (пароли, небольшие текстовые поля), но попытка вычислить хэш файла размером в 100 Мб таким способом приведет к «зависанию» интерфейса 1С на длительное время.

Способ 3. Использование Менеджера криптографии (штатный кроссплатформенный путь)

Для более надежной реализации на клиенте рекомендуется использовать объект МенеджерКриптографии. Несмотря на название, он умеет не только подписывать файлы, но и просто вычислять хэш. Этот объект доступен на клиенте в Тонком клиенте.

Разберем по шагам, как это реализовать:


// Инициализируем менеджер без указания конкретного сертификата
Менеджер = Новый МенеджерКриптографии("", "", 80); // 80 - тип провайдера по умолчанию
Менеджер.АлгоритмХеширования = "SHA-256";

// Читаем файл в ДвоичныеДанные на клиенте
ДанныеФайла = Новый ДвоичныеДанные("C:\temp\report.pdf");

// Получаем объект ХешДанных
ОбъектХеш = Менеджер.ПолучитьХешДанных(ДанныеФайла);

// Преобразуем в строку
СтрокаХеша = НСтр(ОбъектХеш.Хеш); // Получаем в виде Hex-строки
Сообщить("SHA-256 хэш: " + СтрокаХеша);

Преимущества: это штатный механизм платформы, он работает быстрее, чем чистый код 1С, и поддерживает современные алгоритмы (SHA-256). Однако на компьютере должен быть установлен криптопровайдер (в Windows он есть по умолчанию).

Способ 4. Хеширование в веб-клиенте через HTML5 Web Crypto API

Когда речь заходит о Safari на iPad или Google Chrome, где нет ни COM, ни возможности запускать локальные файлы через криптографию 1С, мы можем использовать возможности браузера. Современные браузеры поддерживают window.crypto.subtle.digest.

Посмотрим на пример реализации через поле HTML-документа:

  1. Размещаем на форме скрытое ПолеHTMLДокумента.
  2. Загружаем в него минимальный JS-код, который принимает данные и возвращает хэш.
  3. Передаем данные из 1С через window.postMessage или через событие ПриНажатии.

Этот метод позволяет считать хэш даже на мобильных устройствах без передачи данных на сервер 1С, используя вычислительные мощности браузера.

Способ 5. Использование PowerShell (современная альтернатива для Windows)

Если CertUtil по какой-то причине недоступен или требуется получить хэш в формате, который легче парсить, проанализируем использование PowerShell. Команда Get-FileHash возвращает объект, который легко преобразовать в текст.


// Пример формирования команды для PowerShell
Путь = "C:\docs\contract.docx";
КомандаPS = "powershell -command ""(Get-FileHash -Path '" + Путь + "' -Algorithm SHA256).Hash""";

Выполнитель = Новый COMОбъект("WScript.Shell");
Результат = Выполнитель.Exec(КомандаPS).StdOut.ReadAll();
Сообщить("Результат из PowerShell: " + СокрЛП(Результат));

Сравнительный анализ методов

Подводя итог, выберем подходящий инструмент в зависимости от условий:

Важный совет: всегда учитывайте кодировку при расчете хэша строки. Хэш от строки в кодировке UTF-8 и хэш от той же строки в кодировке Windows-1251 будет абсолютно разным. Перед расчетом всегда приводите данные к единому стандарту с помощью объекта ЗаписьТекста или преобразования в ДвоичныеДанные.

← На главную