При разработке мобильных приложений и систем обмена данными на платформе 1С программисты часто сталкиваются с необходимостью скрыть пароли или ключи доступа. Однако использование стандартных функций хеширования иногда преподносит сюрпризы: один и тот же код может выдавать разные результаты на разных устройствах или даже на одном устройстве через некоторое время. В этой статье мы подробно разберем, почему «плавает» хеш, как правильно работать с типами данных и какие современные механизмы 1С версии 8.5 позволяют надежно защитить конфиденциальную информацию.
Рассмотрим ситуацию, когда разработчик пытается получить хеш от результата математического выражения. На первый взгляд, код кажется логичным: вычисляется число, преобразуется в строку, и от этой строки берется MD5. Но именно на этапе преобразования в строку кроется главная ловушка. Проанализируем типичную ошибку:
СтранноеЧисло = 3 + 7 * 2 / 8 + 5 - 3; // Результат 6.75
Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
Хеш.Добавить(Строка(СтранноеЧисло));
Возврат Base64Строка(Хеш.ХешСумма);
Проблема заключается в функции Строка(). В платформе 1С преобразование числа в строку сильно зависит от региональных настроек (локали) сеанса или операционной системы. Разберем по шагам, что происходит внутри системы:
Строка() добавит неразрывный пробел (символ с кодом 160) для разделения тысяч. Наличие или отсутствие этого пробела полностью меняет входные данные для хеширования.Чтобы гарантировать стабильность хеша, мы должны исключить влияние региональных настроек. Для этого вместо функции Строка() всегда следует использовать функцию Формат() с явным указанием параметров. Выясним, как сделать код надежным:
// Используем параметр ЧГ=0, чтобы убрать разделители групп
// И явно задаем разделитель дробной части, если это необходимо
СтрокаДляХеша = Формат(СтранноеЧисло, "ЧГ=0; ЧРД=.");
Хеш.Добавить(СтрокаДляХеша);
Еще более надежный способ — работать напрямую с двоичными данными или использовать XML-сериализацию, которая всегда выдает канонический вид числа. Посмотрим на пример функции, которая корректно обрабатывает разные типы входных данных:
Функция КонтрольнаяСуммаСтрокой(Знач Данные, Знач Алгоритм = Неопределено) Экспорт
Если Алгоритм = Неопределено Тогда
Алгоритм = ХешФункция.MD5;
КонецЕсли;
ХешированиеДанных = Новый ХешированиеДанных(Алгоритм);
// Если передано не строковое значение, используем XML-сериализацию для стабильности
Если ТипЗнч(Данные) <> Тип("Строка") И ТипЗнч(Данные) <> Тип("ДвоичныеДанные") Тогда
Данные = ЗначениеВСтрокуXML(Данные);
КонецЕсли;
ХешированиеДанных.Добавить(Данные);
Возврат СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
КонецФункции
Платформа 1С 8.5 привносит новые механизмы работы с безопасностью. Если ваша задача — скрыть пароль в мобильном приложении, которое обращается к бэкенду, использование простых хешей в коде является «защитой от честных людей». Проанализируем, почему это так:
Любой опытный пользователь может декомпилировать байт-код модуля или перехватить трафик. Если вы просто сравниваете хеш от введенного пароля с «зашитым» в коде, злоумышленник может подменить саму логику проверки (вернуть Истина вместо Ложь).
Менеджер безопасного хранилища: В современных версиях 1С (включая 8.5) реализован объект МенеджерБезопасногоХранилища. Это профессиональное решение, которое использует системные механизмы ОС (Keystore в Android и Keychain в iOS). Рассмотрим преимущества этого подхода:
Если архитектура системы требует передачи пароля на сервер (как в случае автора вопроса), рассмотрим альтернативные методы сокрытия данных, кроме математических формул:
ХешФункция.SHA256 и ГОСТ. Рекомендуется переходить на них.В исходном вопросе автор использовал конструкцию Сред(Base64Строка(Хеш.ХешСумма), 2, 16). Проанализируем эту ошибку. Обрезание Base64-строки — это плохая практика. Base64 — это лишь способ представления двоичных данных (хеша) в текстовом виде. Когда вы обрезаете эту строку, вы не просто сокращаете длину, вы удаляете значимые биты информации, что критически снижает криптостойкость хеша. Если вам нужен короткий идентификатор, лучше использовать алгоритм CRC32 или брать первые N байт напрямую из ДвоичныеДанные хеш-суммы до их кодирования в Base64.
Подводя итог, можно сказать: "странности" в расчете хеша в 1С всегда имеют логическое объяснение, связанное с типами данных. Используйте Формат(), избегайте неявных преобразований и доверяйте хранение паролей специализированным объектам платформы, таким как МенеджерБезопасногоХранилища.