Ответ 1
Об этом:
"Это потому, что я не только хочу проверить, что подписанный PDF файл аутентичным, но также и тем, что он имеет тот же неподписанный PDF, что у меня есть запись"
Предполагая, что вы просто хотите знать, что документ, который вы получаете на своем сервере, является подлинным:
При создании подписанного документа у вас есть выбор для подписания только одной части файла или всего документа. Затем вы можете использовать подпись "всего документа", и если документ, который вы вернете на своем сервере, является "аутентичным" (что означает, что проверка подписи прошла успешно), то это точно тот же самый документ, который вы записали.
Стоит отметить, что существуют два типа подписей PDF, подписей о подписке и подписей на сертификацию. Из документа Цифровые подписи в PDF из Adobe:
Подписи подписи(...), где кто-то подписывает документ для показа согласия, одобрения или принятия. Сертифицированный документ - это документ, подпись сертификата, поданная инициатором, когда документ готова к использованию. Создатель указывает, какие изменения разрешены; выбирая один из трех разрешенных модификаций:
- без изменений
- только заполнение формы
- заполнение формы и комментирование
Предполагая, что вы хотите сопоставить определенный подписанный документ, который вы получили на своем сервере, с его неподписанным эквивалентом в базе данных:
Для идентификации документа я бы посоветовал разобраться с ним отдельно. Как только документ можно открыть, может быть создан хеш (например, md5) из конкатенации распакованного содержимого всех его страниц, а затем сравнить его с другим похожим хешем из исходного документа (который может быть сгенерирован один раз и сохранен в базе данных).
Причина, по которой я буду делать это, заключается в том, что она будет независимой от типа подписи, которая была использована в документе. Даже когда поля формы редактируются в файле PDF или добавляются аннотации или создаются новые подписи, содержимое страницы никогда не изменяется, оно всегда будет оставаться неизменным.
Если вы используете iText, вы можете получить массив байтов содержимого страницы, используя метод PdfReader.getPageContent и использовать результат для вычисления хеша MD5.
Код в Java может выглядеть следующим образом:
PdfReader reader = new PdfReader("myfile.pdf");
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
int pageCount = reader.getNumberOfPages();
for(int i=1;i <= pageCount; i++)
{
byte[] buf = reader.getPageContent(i);
messageDigest.update(buf, 0, buf.length);
}
byte[] hash = messageDigest.digest();
Кроме того, если сервер получает файл, который вышел без знака, он был подписан, подпись может ссылаться только на одну часть файла, а не на всех. В этом сценарии для дайджеста может быть недостаточно, чтобы идентифицировать файл.
Из спецификации PDF (выделенные жирным шрифтом в моей учетной записи):
Подписи создаются путем вычисления дайджеста данных (или части данные) в документе и сохранение дайджеста в документе. (...) Существует два определенных метода вычисления воспроизводимого дайджеста содержимое всего или части файла PDF:
-A байтовый дайджест диапазона вычисляется по диапазону байтов в файле, указанному в записи ByteRange в словаре подписи. Эта диапазон - это, как правило, весь файл, включая словарь подписи но за исключением самого значения подписи (запись содержимого).
-Объектный дайджест (PDF 1.5) вычисляется с помощью выборочно, ходя по поддереву объектов в памяти, начиная с ссылочного объекта, который обычно является корневым объектом. Полученный в результате дайджест вместе с информация о том, как она была вычислена, помещена в подпись справочный словарь (...).