Добавление цифровой подписи в PDF с видимой меткой времени и полем Reason с помощью ESIG/DSS

Я пытаюсь понять и реализовать решение на основе проекта Службы цифровой подписи, спонсируемого Европейской комиссией. В настоящее время я преуспел в использовании абстракции, предоставленной приложением DSS-DEMO, упомянутой в вышеупомянутой ссылке на github, с помощью клиентского программного обеспечения Nowina NexU. Я хочу подписать цифровой документ PDF со следующей конфигурацией:

  • нет контейнера
  • PAdES подпись
  • окутанный
  • PAdES_BASELINE_LT уровень подписи
  • Алгоритм дайджеста SHA256

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

Я также хочу заполнить поле "Причина" подписи - оно впоследствии отображается при просмотре свойств подписи с помощью программы, подобной Adobe Acrobat Reader.

Мои проблемы до сих пор следующие, и я не могу найти ни примеров, ни другой информации о них.

  1. Если я хочу отобразить метку времени подписи, которую я получу от службы Authority Timestamp, как я получу ее, поскольку связь с сервером меток времени осуществляется во время процесса подписания, то есть после указания параметров, как я упоминал выше. Я думаю, мне нужно копаться в коде DSS и делать все шаги, сделанные там для меня лично.
  2. В настоящее время происходит странная вещь. Похоже, что подписи считаются действительными или, по крайней мере, НЕИЗВЕСТНЫМИ, когда я указываю жестко запрограммированную причину (например, "тест-тест") или вообще не вижу причину. Когда я заполняю его из результатов чего-то другого, подпись недействительна. Поскольку подобные вещи обычно не происходят по волшебству, я, должно быть, делаю что-то ужасно неправильно.

Код организован примерно так: существует REST-связь между двумя компьютерами - сервером и клиентом с установленным NexU. NexU осуществляет всю связь со смарт-картой или любым другим хранилищем сертификатов на клиентском компьютере - он обменивается значением дайджеста и подписанным значением дайджеста с сервером. Есть, среди прочего, две специфические фазы в коде сервера:

  • getDataToSign - здесь дайджест рассчитывается по содержанию PDF
  • signDocument - здесь происходит фактическое подписание - (вложение подписи в документ, я полагаю?).

Я даю обеим фазам множество параметров, которые, помимо прочего, указывают метку времени подписания, причину и визуальные параметры текста, который я хочу отобразить на первой странице. Я делаю это с одинаковыми параметрами для обеих фаз (потому что я не уверен, на какой фазе я должен дать какую)

Моя дата подписания - не логично ли, чтобы она была настолько близка к отметке времени сервера авторизации, насколько это возможно? Хорошо, я устанавливаю текущую метку времени моего собственного сервера в момент начала процесса подписания.

Я устанавливаю Reason, используя PAdESSignatureParameters.setReason. Любое полезное понимание приветствуется - спасибо.

1 ответ

Решение
  1. Я решил странную проблему с полем Reason в Signature.
  2. Похоже, я не вижу, чтобы дата подписания отличалась от метки времени, предоставленной властями.

Объяснение следует.

Что касается первого случая, это была моя вина. Для уточнения, насколько я понимаю, параметры подписи предоставляются методам DSS два раза с использованием метода SigningService.fillParameters().

  1. в SigningService.getDataToSign(...), а затем
  2. в SigningService.signDocument(...)

Это важно сделать в обоих методах, потому что в первый раз вычисляется хэш / дайджест документа, подлежащего подписанию. Поскольку я выбрал подпись, которая должна быть заключена в оболочку, то есть должна содержаться в документе, который будет подписан, нам нужно сначала применить подпись, а затем вычислить дайджест на основе этого "окончательного" документа.

Насколько я видел в коде DSS (приблизительно), представление загруженного PDF в памяти подписывается, и его дайджест вычисляется во время getDataToSign - но результат отбрасывается.

Во время самого метода signDocument (между тем дайджест отправляется обратно на клиент с установленным NexU и возвращается обратно на сервер с подписью), загруженный PDF снова подписывается, его дайджест вычисляется снова, но на этот раз фактический подписанный дайджест (мы получили от клиента) также применяется к документу - и результат этой операции в памяти отправляется обратно клиенту в виде подписанного документа PDF.

Что я делал неправильно, так это то, что в первый раз я терял переменную, которую собирался добавить в качестве причины (она была потеряна где-то в атрибутах модели - я не передавал ее где-то между запросами), в результате чего моей первой карты параметров, переданной в getDataToSign, отличной от второй карты параметров - поэтому вполне логично, что фактический хэш / дайджест документа отличался от дайджеста в сохраненной подписи (потому что в то время -подписан был подсчитан, я не передавал причину). Вот почему, когда я передавал жестко закодированное значение, поскольку оно было жестко закодировано, оно присутствовало во время обоих вызовов fillParameters. Это была такая глупая ошибка, я знаю. Я должен был знать это, потому что не было абсолютно ничего о каких-либо трудностях с передачей Reason (или других полей, таких как Location) в Подпись.

Кстати, подпись выполняется с использованием Apache PDFBox, и это делается постепенно.

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

  1. Мой сервер может иметь немного необычное местное время
  2. Поскольку весь процесс подписания происходит между двумя компьютерами (сервером и клиентом с установленным NexU, а также со смарт-картой), а также потому, что появляются разные диалоговые окна с запросом пароля и т. Д., - все это откладывает фактическое подписание и обращение к метке времени делается во время самого последнего шага. Конечно, я не уверен, что это проблема, так как теоретически авторитетные метки времени не знают о фактическом изменении содержимого - в этом случае была бы вызвана предыдущая ошибка...

Это больше похоже на это - конечно, я открыт для других комментариев и ответов. Спасибо!

Другие вопросы по тегам