Сертификат виден с сервера, а подписать им не получается
Иван Недомолков · Chop etilgan:
Задача формулируется одинаково у всех: нужно, чтобы документ подписывался без человека. Регламентное задание отправляет отчётность, счета-фактуры или накладные ночью, а ЭЦП требует, чтобы кто-то вставил ключ и ввёл пароль.
Дальше начинается разбор, который почти всегда идёт по одному сценарию: сертификат в списке виден, флаг подписи на сервере поставлен, а подпись не выходит. Разберём, почему.
Три разные вещи, которые называют одним словом
Под “подписью на сервере” в 1С понимают минимум три несовпадающих вещи, и путаница между ними съедает основное время:
- Где выполняется вычисление подписи. Это то, чем управляет флаг в настройках.
- Где физически лежит закрытый ключ и под какой учётной записью он доступен.
- Кто вводит пароль к контейнеру, когда контейнер защищён паролем.
Флаг переносит только первое. Он не переносит контейнер и не отменяет пароль. Поэтому включение флага само по себе не меняет ничего, если пункты два и три не решены отдельно.
Почему “виден в списке” не равно “можно подписать”
Вот механизм, из-за которого разбор уходит не туда.
Список сертификатов в интерфейсе собирается по хранилищу, а хранилище отдаёт открытую часть сертификата. В платформе это выглядит так:
Менеджер = Новый МенеджерКриптографии(...);
Хранилище = Менеджер.ПолучитьХранилищеСертификатов(...);
Массив = Хранилище.ПолучитьВсе();
ПолучитьВсе() вернёт массив сертификатов, и в нём будет ровно то, что нужно для
отображения: субъект, издатель, отпечаток, срок. Закрытого ключа там нет и быть не может.
Отсюда правило, которое экономит часы: наличие сертификата в списке доказывает, что платформа видит открытую часть, и ничего не говорит о доступе к закрытому ключу. Проверять надо не список, а подпись: попробовать подписать тестовые данные тем же кодом, который будет работать в задании, и посмотреть на исключение.
Отдельная ловушка при отладке: справочники сертификатов в типовых конфигурациях идентифицируют записи по отпечатку, а отпечаток одинаков у сертификата и на клиенте, и на сервере. Запись в справочнике заводится с клиента и после этого выглядит одинаково независимо от того, доступен ли ключ серверу.
Под какой учётной записью лежит контейнер
Здесь ошибаются чаще всего. Сервер 1С это не одна учётная запись.
- ragent это служба агента сервера,
- rphost это рабочий процесс, в котором реально исполняется ваш код.
Контейнер закрытого ключа в профиле пользователя виден тому, под кем этот профиль. Значит, контейнер должен быть доступен учётной записи, под которой запущен rphost, а не той, под которой вы зашли на сервер по RDP и всё проверили руками.
Практическая проверка занимает минуту: посмотреть в диспетчере задач или в консоли кластера, под кем работает rphost, и убедиться, что контейнер лежит в профиле именно этой учётной записи. Схема “поставил ключ под своей доменной учёткой на сервере” не работает никогда, хотя выглядит убедительно.
Второе, про что забывают: у объекта МенеджерКриптографии есть свойство
ИспользованиеИнтерактивногоРежима. На сервере интерактивный режим надо выключать явно,
иначе криптопровайдер попытается показать диалог ввода пароля там, где показывать его некому,
и задание встанет без внятной ошибки. Пароль передаётся свойством
ПарольДоступаКЗакрытомуКлючу.
Задача “один ключ на многих” решается не здесь
Частая исходная формулировка: у нас пять бухгалтеров, ключ один, хотим положить его на сервер, чтобы подписывали все.
Серверный контейнер эту задачу не решает, он решает соседнюю. Один ключ на несколько пользователей это про облачную подпись: сервис DSS в составе БСП или облачный сертификат оператора. Там закрытый ключ физически не покидает защищённый контур, а 1С обращается к нему по протоколу.
Разница принципиальная: серверный контейнер это “подписывает процесс без человека”, облачная подпись это “подписывают несколько человек одним ключом с разграничением прав”. Второе через первое не делается.
Отдельно про интерактивный сценарий: в связке с 1С:Отчётностью серверная подпись упирается в то, что сертификат подтягивается из настроек взаимодействия, а мастер добавления сертификата работает с клиента и серверный контейнер в списке не покажет по построению. Обход есть, через заведение записи из файла сертификата, но для интерактивной работы схема остаётся неудобной. Регламентные задания это другой случай, и там серверный контейнер обязателен.
Третий путь: файл ключа и компонента вендора
Есть сценарий, где хранилище сертификатов Windows не участвует вообще, и он часто оказывается проще всех предыдущих.
Ключ хранится файлом, а подпись выполняет внешняя компонента криптографии, которую поставляет вендор фискальной системы. Тогда вопрос “под какой учёткой лежит контейнер” исчезает вместе с контейнером: компонента получает путь к файлу и пароль и возвращает подпись.
Так устроен казахстанский контур ИИС ЭСФ. Ключ организации в формате .p12 лежит внутри
информационной базы, пароль в безопасном хранилище, а подпись выполняет компонента Kalkan
на сервере 1С. Замеры с нашего стенда: сессия портала, которая открывается подписанным
тикетом, поднимается за 2,2 секунды, подпись двух документов пачкой занимает 1,7 секунды
против 0,8 секунды на один документ, то есть пакетный вызов почти бесплатен по сравнению
с единичным.
Компонента в такой схеме нужна на каждом рабочем сервере кластера. Если на сервере, где выполняется код, нет нужной библиотеки криптографии, подпись не формируется, а 1С сообщает совсем о другом: в одном нашем разборе это выглядело как “Поле объекта не обнаружено (responseObject)”.
Что важно в этой схеме кроме удобства: временный файл ключа надо удалять на всех путях выхода, включая ошибочные. Файл закрытого ключа, оставшийся на диске сервера после исключения, это инцидент безопасности, а не мусор в каталоге.
Что выбрать под свою задачу
| Задача | Решение | Чем платите |
|---|---|---|
| Регламентное задание подписывает само | контейнер под учёткой rphost либо файл ключа плюс компонента | ключ доступен процессу, значит доступен и коду в этой базе |
| Один ключ на нескольких человек | облачная подпись, DSS в БСП | зависимость от оператора и его тарифа |
| Интерактивная подпись в 1С:Отчётности | остаётся клиентская схема | человек у монитора |
И общее правило, ради которого писалась статья: проверять надо подписью, а не списком. Список сертификатов отвечает на вопрос “видит ли платформа открытую часть”. Вопрос “может ли сервер подписать” проверяется только попыткой подписать, в том же процессе и под той же учётной записью, где это будет работать в бою.
Что рядом
Про то, как эта механика применяется в казахстанском контуре, у нас есть разбор автоматизации отправки ЭСФ и готовый модуль Автопилот ИИС ЭСФ, где серверная подпись уже собрана и проверена на боевом портале. Бывает и так, что до подписи дело не доходит: задание по расписанию не стартует вовсе, а журнал пуст. Тогда ключ ни при чём, и причину, от флага на кластере до пользователя задания, которого нет в базе, называет обработка про регламентное задание, которое не выполняется.
Если вы пришли сюда с ошибкой NCALayer, а не с задачей про регламентные задания, вам нужен другой разбор: NCALayer не запущен и настройка обмена с ИС ЭСФ.