Как правильно реализовать подпись PKCS#7 для вложений СМЭВ в 1С?

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

Интеграция с системой СМЭВ часто сопровождается трудностями при работе с электронной подписью. Одной из самых частых ошибок является сообщение от сервера СМЭВ: «Дайджест не прошел проверку!». Давайте подробно разберем, почему это происходит и как правильно реализовать процесс подписания, чтобы избежать двойного хеширования данных.

Понимание причины ошибки «Дайджест не прошел проверку»

Ключевая проблема при работе с объектами CAdESCOM заключается в выборе метода подписания. В 1С разработчики часто используют стандартный объект МенеджерКриптографии или метод Sign. Важно понимать разницу:

Пошаговая реализация процесса подписания

Для корректной работы со СМЭВ нам необходимо подготовить данные, вычислить дайджест и правильно передать его в RawSignature. Разберем этот процесс по шагам.

Шаг 1: Вычисление хеша

Используйте объект CAdESCOM.HashedData для получения корректного хеша. Важно правильно настроить кодировку данных, чтобы избежать проблем с форматами.


// Инициализация объектов
oHashedData = Новый COMОбъект("CAdESCOM.HashedData");
CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101; 
oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;

// Установка кодировки (например, BASE64, если передаем данные в этом формате)
CADESCOM_BASE64_TO_BINARY = 1;
oHashedData.DataEncoding = CADESCOM_BASE64_TO_BINARY;

// Вычисление хеша
oHashedData.Hash(ДанныеДляПодписиBase64);
ХэшХексСтрока = oHashedData.Value;
ХэшДвоичный = ПолучитьДвоичныеДанныеИзХеша(ХэшХексСтрока);

Шаг 2: Использование SignHash вместо стандартного подписания

Чтобы избежать двойного хеширования, мы будем использовать метод SignHash. Обратите внимание на использование метода SetHashValue — это критический момент для передачи уже готового дайджеста.


oRawSignature = Новый COMОбъект("CAdESCOM.RawSignature");
oHashedData.DataEncoding = CADESCOM_BASE64_TO_BINARY;
oHashedData.Algorithm = CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;

// Подставляем уже готовый хеш, чтобы метод SignHash не вычислял его заново
oHashedData.SetHashValue(Base64Строка(ХэшДвоичный));

// Вычисляем «сырую» подпись
sRawSignature = oRawSignature.SignHash(oHashedData, oCertificate);

// Получаем итоговую подпись
ПодписьДвоичная = ПолучитьДвоичныеДанныеИзХеша(sRawSignature);

Важные рекомендации при работе со СМЭВ

  1. Проверка эндианности (Endianness): В некоторых реализациях СМЭВ при ручном формировании подписи может требоваться изменение порядка байтов в хеше. Если стандартный метод SignHash дает ошибку, проверьте эталонные значения хеша, которые присылает сервис СМЭВ, и сравните их с вашим результатом побайтово.
  2. Использование внешних компонент: Если работа со «сырыми» методами КриптоПро вызывает сложности с канонизацией XML (трансформация СМЭВ), рекомендуем рассмотреть использование специализированных внешних компонент, таких как ExtraCryptoAPI. Эти инструменты имеют встроенные методы (например, TransformSMEV), которые учитывают специфические требования СМЭВ к структуре XML, что избавляет от написания сложных алгоритмов вручную.
  3. Валидация через консольные утилиты: Прежде чем отлаживать код в 1С, получите хеш вашего файла с помощью консольной утилиты cryptcp от КриптоПро. Если результат утилиты совпадает с вашим результатом в 1С, значит, алгоритм хеширования верный и проблему нужно искать в структуре передаваемого XML или формате подписи (PKCS#7).
  4. Кодировки строк: При работе со строковыми данными помните, что CAdESCOM по умолчанию ожидает определенную кодировку (обычно UCS-2LE). Если вы хешируете текст, используйте System.Text.UTF8Encoding, чтобы преобразовать строку в массив байтов перед передачей в HashedData.Hash. Это обеспечит стабильный результат, не зависящий от настроек локали сервера 1С.

Следуя этим рекомендациям и переключившись на использование SignHash вместо высокоуровневых методов, вы сможете успешно пройти валидацию дайджеста на стороне СМЭВ и обеспечить корректный обмен данными.

← На главную