Как реализовать шифрование данных в 1С с использованием аппаратных ключей RuToken и контейнеров KeePass?

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

В современных корпоративных системах на базе 1С:Предприятие вопросы информационной безопасности (ИБ) выходят на первый план. Стандартных механизмов платформы, таких как ХранилищеЗначения с простым паролем, часто бывает недостаточно для защиты критически важных финансовых или персональных данных. Рассмотрим продвинутое решение задачи: шифрование реквизитов объектов 1С таким образом, чтобы доступ к ним был возможен только при наличии физического аппаратного ключа (например, RuToken), а сам процесс расшифровки был прозрачным для пользователя.

Постановка задачи и выбор архитектуры

Перед нами стоит цель — обеспечить хранение конфиденциальных строк или файлов внутри базы данных 1С, исключив ввод пароля с клавиатуры. Вместо этого пароль (мастер-ключ) должен извлекаться непосредственно из защищенной памяти аппаратного токена. Для реализации этой задачи мы проанализируем связку технологий: 1С, менеджер паролей KeePass (формат KDBX 4) и интерфейс PKCS#11 для работы с токенами.

Разберем, почему прямое использование встроенного языка 1С для таких задач затруднительно. Платформа 1С имеет ограничения при работе с низкоуровневыми библиотеками C++ (DLL) и специфическими криптографическими протоколами. Наиболее надежным подходом является создание Middleware (прокси-приложения) на языке C#, которое возьмет на себя всю «магию» работы с железом и криптографией.

Проектирование C# Middleware (Прокси)

Проанализируем структуру нашего прокси-приложения. Мы будем использовать его как изолированный дочерний процесс. Это критически важно для безопасности: если 1С будет обращаться к ключу напрямую через COM, риск утечки мастер-пароля в память основного процесса возрастает.

Для взаимодействия выберем стандартные потоки ввода/вывода (StdIn и StdOut). Рассмотрим преимущества этого метода: данные передаются в рамках оперативной памяти между родителем и потомком, что защищает их от перехвата сетевыми снифферами, в отличие от локальных HTTP-запросов. Обмен данными реализуем в формате JSON.

Основные компоненты нашего прокси-приложения:

  1. Pkcs11Interop: библиотека для работы с RuToken. Она позволяет инициализировать сессию, ввести ПИН-код и прочитать защищенный объект (ключ) с токена.
  2. KeePassLib: официальная библиотека от создателей KeePass. Мы будем использовать её для создания и модификации баз данных .kdbx.
  3. System.Text.Json: для сериализации команд от 1С.

Алгоритм работы с аппаратным ключом

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

  1. Пользователь вставляет RuToken в USB-порт и запускает сеанс 1С.
  2. При открытии формы защищенного объекта 1С запускает наш EXE-прокси командой WScript.Shell.Exec().
  3. Прокси запрашивает ПИН-код (один раз за сессию). После успешного ввода прокси обращается к токену по интерфейсу PKCS#11, находит объект с заданной меткой (например, SecretMasterKey) и считывает его значение.
  4. Это значение используется как CompositeKey для открытия базы KeePass. Само значение ключа никогда не возвращается обратно в 1С.

Интеграция на стороне 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;
КонецЕсли;

Важный нюанс: Чтобы сделать механизм универсальным, внедрим паттерн «Префикс реквизитов». Мы договоримся, что все реквизиты, требующие шифрования, начинаются с префикса хд_ (например, хд_ЛичныйНомер). Проанализируем ситуацию: в общей форме или модуле мы можем программно обойти метаданные объекта, найти все такие поля и автоматически отправить их на шифрование в прокси при сохранении объекта.

Технические тонкости и решение проблем

Разберем подводные камни, с которыми можно столкнуться при реализации:

  1. Разрядность (x86 vs x64): Драйверы RuToken (rtPKCS11ECP.dll) имеют разную разрядность. Если сервер 1С 64-битный, прокси-приложение также должно быть собрано под x64, а библиотека драйвера должна находиться в системных директориях или рядом с EXE.
  2. Алгоритм Argon2: Новые версии KeePass используют Argon2 для защиты от перебора. Это требует наличия нативных библиотек KeePassLibN.x64.dll в папке с вашим прокси. Без них открытие базы KDBX 4 выдаст ошибку.
  3. Безопасность временных файлов: Хотя база KeePass сама по себе зашифрована, рекомендуется использовать метод УдалитьФайлы() сразу после того, как 1С прочитала данные из временного файла KDBX обратно в ХранилищеЗначения.

Альтернативный подход: Native API

Проанализируем более производительный вариант. Вместо запуска внешнего процесса EXE можно написать Внешнюю компоненту 1С по технологии Native API на C++. Это позволит загрузить функционал шифрования прямо в адресное пространство процесса 1С. В этом случае взаимодействие будет происходить через вызов методов объекта компоненты:


ПодключитьВнешнююКомпоненту("ОбщийМакет.КриптоКомпонента", "Crypto");
Менеджер = Новый ("AddIn.Crypto.RutokenWorker");
Если Менеджер.ИнициализироватьТокен(ПинКод) Тогда
    Данные = Менеджер.РасшифроватьСтроку(ЗашифрованныеДанные);
КонецЕсли;

Такой подход работает быстрее, так как исключает накладные расходы на запуск процесса и сериализацию JSON, но требует более глубоких знаний системного программирования.

Заключение и выводы

Реализованная схема обеспечивает «параноидальный» уровень защиты: даже если злоумышленник получит полный доступ к серверу и копию базы данных 1С, он не сможет прочитать зашифрованные поля без физического обладания вашим RuToken. Мы распределили логику так, что 1С отвечает за интерфейс и хранение контейнеров, а Middleware на C# — за безопасную работу с криптографией и оборудованием. Это гибкое и масштабируемое решение, которое легко внедрить в любую типовую или самописную конфигурацию 1С.

← На главную