Работа с электронными цифровыми подписями (ЭЦП) в среде 1С часто ограничивается стандартным объектом МенеджерКриптографии. Однако при возникновении нестандартных задач — например, программного поиска физического расположения ключа на флешке или массового переноса старых контейнеров в другую директорию — штатных методов становится недостаточно. Разберем детально, как устроена система хранения ключей КриптоПро и какими способами можно программно взаимодействовать с контейнерами.
Прежде всего, проанализируем ситуацию, с которой сталкивается разработчик при использовании метода ПолучитьХранилищеСертификатов. Этот метод возвращает объекты типа СертификатКриптографии, которые содержат информацию из открытой части сертификата (издатель, владелец, сроки действия, отпечаток). Однако в структуре этого объекта отсутствует прямая ссылка на физический путь к папке с закрытым ключом.
Важно понимать, что закрытый ключ КриптоПро — это не один файл, а полноценный контейнер. Физически он представляет собой папку, внутри которой находятся шесть файлов с расширением .key:
header.keymasks.keymasks2.keyname.keyprimary.keyprimary2.keyЕсли ключи хранятся на съемном носителе (флешке), папка с этими файлами должна находиться строго в корневом каталоге или, в некоторых конфигурациях, в папке первого уровня. В противном случае криптопровайдер просто не увидит контейнер.
Рассмотрим стандартный подход, принятый в 1С. Вместо поиска физического пути к файлам, программная логика обычно строится на использовании отпечатка сертификата. Это уникальный идентификатор, который позволяет однозначно связать сертификат в хранилище Windows с его закрытым ключом, где бы тот ни находился (в реестре, на токене или флешке).
Проанализируем пример получения отпечатка:
Хранилище = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатов.ПерсональныеСертификаты);
Сертификаты = Хранилище.ПолучитьВсе();
Для Каждого Сертификат Из Сертификаты Цикл
Отпечаток = Сертификат.Отпечаток;
// Используем отпечаток для поиска нужного ключа
КонецЦикла;
Если ваша задача — выбрать нужный ключ для подписания, этого метода достаточно. Но если цель — переместить файлы (как в случае с переносом старых ключей), перейдем к более глубоким методам.
Поскольку 1С скрывает физические пути для обеспечения безопасности, мы можем обратиться к системному реестру Windows. КриптоПро хранит сведения о зарегистрированных контейнерах в определенных ветках. Проанализируем, где искать информацию:
HKEY_CURRENT_USER\SOFTWARE\Crypto Pro\Settings\Users\{SID}\KeysHKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Crypto Pro\Settings\Users\{SID}\KeysЗдесь {SID} — это уникальный идентификатор безопасности пользователя. В этих ветках можно программно прочитать имена контейнеров. Выясним причину, почему это полезно: в параметрах ключа часто указан идентификатор накопителя, что позволяет понять, на каком диске (A:, E:, F:) находится контейнер.
Для реализации этого в 1С воспользуемся COM-объектом WScript.Shell:
Shell = Новый COMОбъект("WScript.Shell");
ПутьРеестра = "HKEY_CURRENT_USER\Software\Crypto Pro\Settings\Users\" + ИдентификаторПользователя + "\Keys\";
// Далее выполняем чтение параметров через Shell.RegRead()
Разберем вариант использования внешних утилит, поставляемых вместе с КриптоПро CSP. Это наиболее надежный способ программного получения полных имен контейнеров (FQCN — Fully Qualified Container Name), которые включают в себя имя считывателя.
Основная утилита для этой задачи — csptest.exe. Посмотрим на пример команды, которую можно запустить из 1С через ЗапуститьПриложение():
Команда: csptest -keyset -enum_containers -verifycontext -fqcn
Результат выполнения этой команды даст нам список всех доступных контейнеров в формате: \\.\имя_считывателя\имя_контейнера. Например, если ключ на флешке, путь может выглядеть как \\.\FLASH\имя_папки_с_ключами. Проанализировав вывод, мы можем точно определить букву диска флешки.
Также полезна утилита certmgr.exe. Она позволяет не только просматривать сертификаты, но и экспортировать их, а также связывать сертификаты с контейнерами.
Если задача заключается в переносе ключей, рассмотрим вариант экспорта в формат .pfx (Personal Information Exchange). Этот файл объединяет в себе и открытый сертификат, и закрытый ключ, защищая их паролем.
Важный нюанс: экспорт в .pfx возможен только в том случае, если при создании (генерации) ключа была установлена отметка "Разрешить экспорт закрытого ключа". Если эта опция не активна, программно создать PFX штатными средствами не получится. В таком случае поможет только физическое копирование папки .key с последующей перерегистрацией в новой системе.
Рассмотрим алгоритм переноса "проблемных" старых ключей:
.key на носителе.certmgr для операции "Установить личный сертификат". Это действие пропишет в системе связь между файлом .cer и новым местоположением закрытого ключа.Для расширения возможностей 1С можно использовать библиотеку CAPICOM (хотя она официально устарела, она все еще часто встречается в проектах) или обращаться к методам .NET через System.Security.Cryptography. Это позволяет получить доступ к свойствам провайдера и параметрам аппаратного считывателя напрямую из кода.
Проанализируем ситуацию с истечением срока действия. При переносе старых ключей помните: у закрытого ключа (контейнера) есть свой срок действия, который часто отличается от срока действия самого сертификата. Даже если файл сертификата валиден, контейнер может быть заблокирован криптопровайдером по истечении времени использования закрытого ключа.
Подведем итог: для простого подписания в 1С используйте отпечаток. Для задач администрирования и переноса используйте связку из реестра Windows и консольных утилит csptest.exe/certmgr.exe, так как это дает полный контроль над физическим расположением контейнеров.