Статус: Участник
Группы: Участники
Зарегистрирован: 28.09.2021(UTC) Сообщений: 20  Сказал(а) «Спасибо»: 3 раз
|
Автор: two_oceans  Автор: NAlexV  но почему-то получаю странную дату подписи 01.01.1970 г. Наверно неправильно проинициализировал объект? Или причина в ином? Что мне нужно исправить, чтобы получить дату и время подписи документа? Добрый день. И правда. Выше же уже писали рецепт: Автор: Андрей *  Главная ошибка: чтобы из значения подписанных данных получить Signers нужно проверить подпись. Если посмотрите внимательнее, то больше никуда "впихнуть" подписанные данные нельзя, только в функцию проверки. При успешной проверке Signers будут заполнены из подписанных данных. У Вас в коде проверки нет, так что значение свойств метки времени на самом деле не проинициализировано из переданных данных, а заполнено по умолчанию нулем (то есть 01 января 1970 года). Не все свойства имеют тип вариант, так что и функция проверки заполнения для них покажет что вроде как заполнены, но на самом деле там "умолчательное" значение. Можно опираться на тип подписи и результат проверки для определения что они заполнены реальным значением. Далее - как передаются данные для проверки: - если подпись отсоединенная (detached), то в Content передаются те же данные, что были подписаны. Если они в Base64, то устанавливаете ContentEncoding. Далее вызываете функцию проверки (наверно VerifyCades подойдет для Вашего случая), в нее передаете подписанные данные, еще вроде бы тип подписи и логический параметр. Тут небольшое замечание, что так как форматы CADES основаны друг на друге, то если указать не тот формат что был при подписи, проверка может дать ложный результат.
Если указать более простой формат, то будет проверено меньшее количество условий и результат может быть ложноположительным. Так возможно использовать CADES_T с неправильной меткой времени везде где требуется CADES_BES или PKCS7 и не получить ошибки. Однако, так не будут заполнены свойства о метке времени. Если указать более сложный, то наоборот результат будет заведомо ложноотрицательным. Поэтому чтобы получить данные метки времени подпись должна пройти успешную проверку как минимум по CADES_T.
- если подпись присоединенная, то Content не заполняется, потому что берется из подписанных данных. Соответственно ContentEncoding ни на что не влияет, можно не устанавливать. Далее вызываете функцию проверки (также передаются подписанные данные, тип подписи и логический параметр). Подробности по функции проверки и в каком виде (BASE64 или HEX) передавать данные лучше уточнить в справке, разные интерфейсы немного отличаются в этом плане. Огромное спасибо! Отличное пояснение. Разобрался в проблеме. Если кому интересно, то финальный код выглядит так: Код:
Функция ПолучитьПодписьДокументаУКЭП(СтруктураСообщения, ПодписываемыеДвоичныеДанные, ОписаниеОшибки) Экспорт
Подпись = Неопределено;
СтрокаОтпечатка = Константы.ОтпечатокДействующегоСертификата.Получить();
Отпечаток = ПолучитьДвоичныеДанныеИзHexСтроки(СтрокаОтпечатка);
Крипто = Новый МенеджерКриптографии("Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", "", 80);
Крипто.ПарольДоступаКЗакрытомуКлючу = Константы.ПарольДоступаКЗакрытомуКлючу.Получить();
Крипто.АлгоритмПодписи = "GR 34.10-2012 256";
Хранилище = Крипто.ПолучитьХранилищеСертификатов(ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты,РасположениеХранилищаСертификатовКриптографии.ДанныеПользователяОС);
НайденныйСертификат = Хранилище.НайтиПоОтпечатку(Отпечаток);
Если НайденныйСертификат = Неопределено Тогда
ОписаниеОшибки = "Подпись файла УКЭП. По отпечатку не найден сертификат в хранилище";
Возврат Неопределено;
КонецЕсли;
Попытка
Если СтруктураСообщения.ПодписьКриптоМенеджером1С Тогда
// Подпись в формате BES
ДанныеОСертификате = ПолучитьДанныеОСертификате(НайденныйСертификат);
СтруктураСообщения.Вставить("ДанныеОСертификате", ДанныеОСертификате);
Подпись = Крипто.Подписать(ПодписываемыеДвоичныеДанные, НайденныйСертификат);
Иначе
// Подпись в формате CADES-T
Крипто = СоздатьCOMОбъектCAdESCOM("CPSigner");
Крипто.Certificate = ПолучитьСертификатПоОтпечатку(СтрокаОтпечатка);
Крипто.KeyPin = Константы.ПарольДоступаКЗакрытомуКлючу.Получить();
Крипто.TSAAddress = "http://qs.cryptopro.ru/tsp/tsp.srf";
ДанныеДляПодписи = СоздатьCOMОбъектCAdESCOM("CadesSignedData");
ДанныеДляПодписи.ContentEncoding = 1; // двоичные данные в кодировке Base64
ДанныеДляПодписи.Content = ПолучитьBase64СтрокуИзДвоичныхДанных(ПодписываемыеДвоичныеДанные);
ТипПодписи = 5; // CADES-T
ВидПодписиОтдельная = Истина;
КодировкаПодписи = 0; // кодировка Base64
ДанныеОСертификате = ПолучитьДанныеОСертификате(НайденныйСертификат);
СтруктураСообщения.Вставить("ДанныеОСертификате", ДанныеОСертификате);
СтрокаПодписи = ДанныеДляПодписи.SignCades(Крипто, ТипПодписи, ВидПодписиОтдельная, КодировкаПодписи);
Если ЗначениеЗаполнено(СтрокаПодписи) Тогда
Подпись = Base64Значение(СтрокаПодписи);
ДанныеДляПроверки = СоздатьCOMОбъектCAdESCOM("CadesSignedData");
ДанныеДляПроверки.ContentEncoding = 1; // двоичные данные в кодировке Base64
ДанныеДляПроверки.Content = ПолучитьBase64СтрокуИзДвоичныхДанных(ПодписываемыеДвоичныеДанные);
ДанныеДляПроверки.VerifyCades(СтрокаПодписи, ТипПодписи, ВидПодписиОтдельная);
Для Каждого Подписант Из ДанныеДляПроверки.Signers Цикл
Если ЗначениеЗаполнено(Подписант.SignatureTimeStampTime) И Подписант.SignatureTimeStampTime <> Дата(1970, 1, 1) Тогда
ДатаВремяПодписи = Подписант.SignatureTimeStampTime;
ДанныеОСертификате.ДатаПодписания = ДатаВремяПодписи;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Исключение
ОписаниеОшибки = "Подпись файла УКЭП. " + ОписаниеОшибки();
КонецПопытки;
Возврат Подпись;
КонецФункции
|