При работе с внешними сервисами, такими как ФГИС "Зерно", часто возникает необходимость использования электронной подписи — для этого подойдёт готовая интеграция 1С с ФГИС Зерно через API. В 1С:Предприятие для этого применяется модуль криптографии, например, КриптоПро CSP. Однако пользователи нередко сталкиваются с ситуацией, когда, несмотря на корректную установку сертификата в систему, серверный код 1С не может его обнаружить. Давайте разберем эту проблему на примере и предложим комплексное решение.
Рассмотрим типовую ситуацию: вы успешно использовали сертификат, когда настраивалась реализация обмена с ФГИС "Зерно", но после его продления и переустановки 1С перестала его "видеть". При этом стандартные средства Windows и утилиты КриптоПро CSP показывают, что сертификат установлен и доступен.
Вот пример кода, который демонстрирует, как обычно выполняется подпись файла методами криптографии в серверной функции 1С:
&НаСервере
Функция ПолучитьСертификатДляПодписи(ПараметрыЗапроса) Экспорт
// Создаем менеджер с указанием установленного модуля криптографии
Попытка
МенеджерКриптографии = Новый МенеджерКриптографии( "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", "", 80);
Если МенеджерКриптографии = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Исключение
Возврат Ложь;
КонецПопытки;
лХранилищеСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов;
ОтпечатокСертификата = "13888A8BD34589567F9B9AFF6499999C0C29C617"; // Условный отпечаток
Сертификат = лХранилищеСертификатов.НайтиПоОтпечатку( ПолучитьДвоичныеДанныеИзHEXСтроки(ОтпечатокСертификата));
Если Сертификат = Неопределено Тогда
Возврат Ложь; // Сертификат не найден
КонецЕсли;
СертификатКриптографииBase64 = Base64Строка(Сертификат.Выгрузить);
СертификатКриптографииBase64 = СтрЗаменить(СертификатКриптографииBase64, Символы.Таб, "");
СертификатКриптографииBase64 = СтрЗаменить(СертификатКриптографииBase64, Символы.ПС, "");
СертификатКриптографииBase64 = СтрЗаменить(СертификатКриптографииBase64, Символы.ВК, "");
ПараметрыЗапроса.Сертификат = СертификатКриптографииBase64;
Возврат Истина;
КонецФункции
В такой ситуации отладка показывает, что вызов лХранилищеСертификатов.НайтиПоОтпечатку() возвращает Неопределено, а при просмотре всех сертификатов через лХранилищеСертификатов.ПолучитьВсе() новый сертификат отсутствует, хотя старый, возможно, все еще виден.
Эта проблема, как правило, сводится к двум основным причинам: местонахождение сертификата в хранилище и права доступа к закрытому ключу для учетной записи, под которой работает сервер 1С:Предприятия. Если вам необходимы более сложные алгоритмы шифрования ГОСТ 34.10-2012 или работа без COM-объектов, стоит изучить альтернативные реализации, но для стандартного модуля КриптоПро причины остаются прежними — для подписания без настройки криптографии на сервере есть интеграция 1С с сервисом Госключ. Давайте разберем эти аспекты подробнее.
Операционная система Windows поддерживает несколько типов хранилищ сертификатов, ключевыми из которых для нас являются:
Сервер 1С:Предприятия (процесс ragent.exe, или Агент сервера 1С) обычно запускается как служба от имени специально выделенной учетной записи (например, USR1CV8, Network Service, Local System или другой пользователь, настроенный администратором). Эта учетная запись не является интерактивным пользователем, вошедшим в систему. Следовательно, она не имеет доступа к хранилищу "Личные" текущего пользователя.
Для корректной работы серверных процессов 1С сертификат с закрытым ключом должен быть установлен в хранилище "Личные" для локального компьютера, а не для текущего пользователя.
Чтобы установить сертификат в хранилище локального компьютера, выполните следующие шаги:
Win + R, введите mmc и нажмите Enter..pfx или .cer) и пароль к закрытому ключу, если он есть. Убедитесь, что вы импортируете закрытый ключ вместе с сертификатом.В коде 1С мы также можем явно указать, какое хранилище использовать. Метод МенеджерКриптографии.ПолучитьХранилищеСертификатов имеет необязательный параметр РасположениеХранилищаСертификатовКриптографии. По умолчанию он использует ДанныеПользователяОС. Для доступа к хранилищу локального компьютера мы должны передать другое значение:
лХранилищеСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов(, РасположениеХранилищаСертификатовКриптографии.ДанныеЛокальногоКомпьютера);
Использование этого параметра критически важно для серверных сценариев.
Даже если сертификат установлен в правильное хранилище локального компьютера, сервер 1С может его не видеть или не использовать, если у учетной записи службы сервера нет прав на доступ к его закрытому ключу. Если в вашей компании требования к безопасности повышены, возможно, вы уже используете хранение секретов в Hashicorp Vault для 1С, однако права на уровне ОС для криптопровайдера все равно необходимо настроить вручную.
Учетная запись, под которой работает служба Агента сервера 1С, должна иметь явные права на чтение закрытого ключа сертификата. Если эти права не настроены, попытка подписания завершится ошибкой или сертификат не будет найден, так как фактически он недоступен для использования.
Давайте пошагово рассмотрим, как предоставить необходимые права:
1C:Enterprise 8...).Local System account, Network Service или конкретный пользователь, такой как .\USR1CV8). Запомните это имя.USR1CV8, Network Service). Если это встроенная учетная запись, убедитесь, что выбрали правильный тип объектов для поиска.После изменения прав доступа обязательно перезапустите службу Агента сервера 1С:Предприятия, чтобы изменения вступили в силу. Это можно сделать через консоль "Службы" Windows или "Диспетчер задач".
certmgr.msc или cpverify.exe, помогут в этом.Итак, основное решение проблемы заключалось в сочетании двух факторов:
После выполнения этих шагов и явного указания хранилища локального компьютера в коде 1С, проблема видимости сертификата, как правило, устраняется, и подписание запросов начинает работать корректно — для организации постоянного обмена документами пригодится модуль юридически значимого ЭДО для 1С.