В современных версиях платформы 1С (8.3.11 и выше) работа с криптографией и хешированием стала тривиальной задачей благодаря встроенным функциям. Однако на платформе 1С 8.2 или в конфигурациях, работающих в режиме совместимости со старыми версиями, разработчики часто сталкиваются с отсутствием метода ХешированиеДанных. Стандартная задача — получить MD5-хеш от строки (например, пароля) и представить его не в виде привычной 32-символьной строки (Hex), а в кодировке Base64. Разберем по шагам, как решить эту задачу, используя COM-объекты и системные библиотеки Windows.
Обычно функции хеширования возвращают результат в шестнадцатеричном виде (например, "d41d8cd98f00b204e9800998ecf8427e"). Это строковое представление 16 байт, из которых состоит MD5. Для формирования Base64 нам нужно именно исходное бинарное представление (массив из 16 чисел), а не его текстовый "слепок". Проблема в 1С 8.2 заключается в том, что стандартные средства работы с бинарными данными крайне ограничены: нет объекта ПотокВПамяти, а объект ДвоичныеДанные не позволяет напрямую манипулировать байтами.
Для начала воспользуемся системным объектом System.Security.Cryptography.MD5CryptoServiceProvider. Он доступен на любой Windows-машине с установленным .NET Framework. Основная задача здесь — правильно передать строку в кодировке UTF-8 и получить обратно массив байтов.
Рассмотрим код функции, которая подготавливает данные:
Функция ПолучитьБинарныйХешMD5(ИсходнаяСтрока)
// Создаем необходимые COM-объекты .NET
ЛокальныйMD5 = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider");
// Используем UTF8 без BOM для совместимости с большинством внешних сервисов
ЛокальныйEnc = Новый COMОбъект("System.Text.UTF8Encoding");
// Преобразуем строку 1С в массив байтов (SafeArray)
МассивБайтов = ЛокальныйEnc.GetBytes_4(ИсходнаяСтрока);
// Вычисляем хеш. Метод возвращает также SafeArray (16 байт)
БинарныйХеш = ЛокальныйMD5.ComputeHash_2(МассивБайтов);
Возврат БинарныйХеш;
КонецФункции
В данном примере крайне важно использовать метод GetBytes_4 и ComputeHash_2. Суффиксы с подчеркиванием и числом в именах методов COM-объектов .NET связаны с перегрузкой методов в исходном коде библиотек. В 1С невозможно вызвать перегруженные методы напрямую, поэтому обращение идет через их порядковые номера в таблице экспорта типов.
После получения БинарныйХеш (который в 1С представлен как COMSafeArray), нам нужно перевести его в Base64. В 1С 8.2 нет встроенной функции Base64Строка() для массивов, поэтому мы воспользуемся еще одним системным объектом — MSXML2.DOMDocument. Этот объект умеет эффективно работать с бинарными данными и их преобразованием в текст.
Проанализируем алгоритм конвертации:
Функция ПреобразоватьВBase64(БинарныеДанные)
// Используем DOMDocument для работы с типами bin.base64
Документ = Новый COMОбъект("MSXML2.DOMDocument");
Элемент = Документ.createElement("base64");
// Устанавливаем тип данных для узла
Элемент.dataType = "bin.base64";
// Записываем наш COMSafeArray в значение узла
Элемент.nodeTypedValue = БинарныеДанные;
// Получаем строковое представление
РезультатBase64 = Элемент.text;
// Очищаем переносы строк, которые DOMDocument может добавлять автоматически
Возврат СтрЗаменить(РезультатBase64, Символы.ПС, "");
КонецФункции
Преимущество этого метода в том, что MSXML2 напрямую принимает SafeArray, который вернул нам .NET объект. Нам не нужно перебирать массив в цикле 1С, что значительно ускоряет работу при массовой обработке данных.
Теперь соберем все части в единую процедуру, которую можно использовать в конфигурации. Проанализируем итоговый код, учитывая нюансы кодировок и очистку объектов.
Функция MD5_Base64(СтрокаПароля) Экспорт
Попытка
// 1. Получаем хеш
КриптоПровайдер = Новый COMОбъект("System.Security.Cryptography.MD5CryptoServiceProvider");
Кодировщик = Новый COMОбъект("System.Text.UTF8Encoding");
БайтыСтроки = Кодировщик.GetBytes_4(СтрокаПароля);
ХешМассив = КриптоПровайдер.ComputeHash_2(БайтыСтроки);
// 2. Конвертируем в Base64 через MSXML
XMLДок = Новый COMОбъект("MSXML2.DOMDocument");
Узел = XMLДок.createElement("temp");
Узел.dataType = "bin.base64";
Узел.nodeTypedValue = ХешМассив;
Результат = СтрЗаменить(Узел.text, Символы.ПС, "");
// 3. Освобождаем COM-объекты
КриптоПровайдер = Неопределено;
Кодировщик = Неопределено;
XMLДок = Неопределено;
Возврат Результат;
Исключение
ЗаписьЖурналаРегистрации("Ошибка хеширования", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
Возврат "";
КонецПопытки;
КонецФункции
System.Text.UTF8Encoding в .NET по умолчанию может добавлять или учитывать BOM. Если вы получаете несовпадающие хеши с внешними системами (например, с PHP-функцией md5()), попробуйте инициализировать кодировщик с параметром Ложь, чтобы принудительно отключить BOM.MD5CryptoServiceProvider и DOMDocument один раз вне цикла и передавайте их в функцию как параметры или используйте переменные модуля.ОбщегоНазначения или специализированных криптографических модулей. В некоторых версиях УПП 1.3 уже реализованы функции математического вычисления MD5 на чистом коде 1С, что избавляет от зависимости от COM-объектов.Используя предложенный подход, мы успешно обходим ограничения старой платформы 1С 8.2, эффективно взаимодействуя с системными компонентами Windows для получения точного бинарного представления данных.