В современных корпоративных системах на базе 1С:Предприятие вопросы информационной безопасности (ИБ) выходят на первый план. Стандартных механизмов платформы, таких как ХранилищеЗначения с простым паролем, часто бывает недостаточно для защиты критически важных финансовых или персональных данных. Рассмотрим продвинутое решение задачи: шифрование реквизитов объектов 1С таким образом, чтобы доступ к ним был возможен только при наличии физического аппаратного ключа (например, RuToken), а сам процесс расшифровки был прозрачным для пользователя.
Перед нами стоит цель — обеспечить хранение конфиденциальных строк или файлов внутри базы данных 1С, исключив ввод пароля с клавиатуры. Вместо этого пароль (мастер-ключ) должен извлекаться непосредственно из защищенной памяти аппаратного токена. Для реализации этой задачи мы проанализируем связку технологий: 1С, менеджер паролей KeePass (формат KDBX 4) и интерфейс PKCS#11 для работы с токенами.
Разберем, почему прямое использование встроенного языка 1С для таких задач затруднительно. Платформа 1С имеет ограничения при работе с низкоуровневыми библиотеками C++ (DLL) и специфическими криптографическими протоколами. Наиболее надежным подходом является создание Middleware (прокси-приложения) на языке C#, которое возьмет на себя всю «магию» работы с железом и криптографией.
Проанализируем структуру нашего прокси-приложения. Мы будем использовать его как изолированный дочерний процесс. Это критически важно для безопасности: если 1С будет обращаться к ключу напрямую через COM, риск утечки мастер-пароля в память основного процесса возрастает.
Для взаимодействия выберем стандартные потоки ввода/вывода (StdIn и StdOut). Рассмотрим преимущества этого метода: данные передаются в рамках оперативной памяти между родителем и потомком, что защищает их от перехвата сетевыми снифферами, в отличие от локальных HTTP-запросов. Обмен данными реализуем в формате JSON.
Основные компоненты нашего прокси-приложения:
.kdbx.Выясним, как именно происходит авторизация. Процесс выглядит следующим образом:
WScript.Shell.Exec().SecretMasterKey) и считывает его значение.CompositeKey для открытия базы KeePass. Само значение ключа никогда не возвращается обратно в 1С.Рассмотрим, как организовать хранение данных в самой конфигурации. Чтобы не загромождать справочники тяжелыми зашифрованными данными, мы будем использовать Регистр сведений. Создадим регистр, где измерениями будут ссылка на объект, а ресурсом — ХранилищеЗначения, содержащее файл .kdbx.
Посмотрим на пример кода 1С для выгрузки и обработки базы:
// Выгружаем контейнер во временный файл
ПутьКФайлу = ПолучитьИмяВременногоФайла("kdbx");
ДанныеКонтейнера = ПолучитьДанныеИзРегистра(ОбъектСсылка); // Получаем Binary Data
ДанныеКонтейнера.Записать(ПутьКФайлу);
// Формируем JSON команду для прокси
Команда = Новый Структура();
Команда.Вставить("action", "read_entry");
Команда.Вставить("db_path", ПутьКФайлу);
Команда.Вставить("entry_title", "FinancialData");
СтрокаJSON = ЗаписатьJSONВСтроку(Команда);
// Отправляем в прокси через StdIn и получаем ответ из StdOut
ОтветJSON = ПроксиПриложение.ОтправитьЗапрос(СтрокаJSON);
Результат = ПрочитатьJSONИзСтроки(ОтветJSON);
Если Результат.Success Тогда
ЗначениеРеквизита = Результат.Data;
КонецЕсли;
Важный нюанс: Чтобы сделать механизм универсальным, внедрим паттерн «Префикс реквизитов». Мы договоримся, что все реквизиты, требующие шифрования, начинаются с префикса хд_ (например, хд_ЛичныйНомер). Проанализируем ситуацию: в общей форме или модуле мы можем программно обойти метаданные объекта, найти все такие поля и автоматически отправить их на шифрование в прокси при сохранении объекта.
Разберем подводные камни, с которыми можно столкнуться при реализации:
rtPKCS11ECP.dll) имеют разную разрядность. Если сервер 1С 64-битный, прокси-приложение также должно быть собрано под x64, а библиотека драйвера должна находиться в системных директориях или рядом с EXE.KeePassLibN.x64.dll в папке с вашим прокси. Без них открытие базы KDBX 4 выдаст ошибку.УдалитьФайлы() сразу после того, как 1С прочитала данные из временного файла KDBX обратно в ХранилищеЗначения.Проанализируем более производительный вариант. Вместо запуска внешнего процесса EXE можно написать Внешнюю компоненту 1С по технологии Native API на C++. Это позволит загрузить функционал шифрования прямо в адресное пространство процесса 1С. В этом случае взаимодействие будет происходить через вызов методов объекта компоненты:
ПодключитьВнешнююКомпоненту("ОбщийМакет.КриптоКомпонента", "Crypto");
Менеджер = Новый ("AddIn.Crypto.RutokenWorker");
Если Менеджер.ИнициализироватьТокен(ПинКод) Тогда
Данные = Менеджер.РасшифроватьСтроку(ЗашифрованныеДанные);
КонецЕсли;
Такой подход работает быстрее, так как исключает накладные расходы на запуск процесса и сериализацию JSON, но требует более глубоких знаний системного программирования.
Реализованная схема обеспечивает «параноидальный» уровень защиты: даже если злоумышленник получит полный доступ к серверу и копию базы данных 1С, он не сможет прочитать зашифрованные поля без физического обладания вашим RuToken. Мы распределили логику так, что 1С отвечает за интерфейс и хранение контейнеров, а Middleware на C# — за безопасную работу с криптографией и оборудованием. Это гибкое и масштабируемое решение, которое легко внедрить в любую типовую или самописную конфигурацию 1С.