IText Извлеките оригинал из подписанного PDF и сравните HASH

У меня есть подписанный PDF. Подпись распространяется на все документы, и она действительна.

Я хочу извлечь исходный PDF-файл, чтобы сравнить его с хэшем неподписанного PDF-файла.

Я извлекаю оригинальный PDF, используя следующий код:

PdfReader reader = new PdfReader(FILESIGNED);
AcroFields acrofields = reader.getAcroFields();
//pdf have a unique signature
String signatureName = acrofields.getSignatureNames().get(0); 
FileOutputStream os = new FileOutputStream(FILEORIGINAL);
InputStream ip = acrofields.extractRevision(signatureName);
int n = 0;
byte bb[] = new byte[1028];
while ((n = ip.read(bb)) > 0)
    os.write(bb, 0, n);
os.close();
ip.close();
reader.close();

Но извлеченный PDF не совпадает с оригиналом. Я бы извлек ревизию до подписи? Является ли это возможным?

Спасибо за помощь. Сара

1 ответ

Решение

Я хочу извлечь исходный PDF-файл, чтобы сравнить его с хэшем неподписанного PDF-файла.

В общем, это невозможно.

Когда iText (или другие библиотеки или приложения для подписи PDF) подписывают PDF, они:

  1. добавить поле формы подписи в PDF (если только поле формы подписи не существует и не выбрано для использования в подписи);
  2. добавить в PDF объект словаря с некоторыми записями, связанными с подписью, в частности с большой записью-заполнителем, в которую в конечном итоге будет вставлен контейнер подписи CMS; этот словарь устанавливается как значение вышеупомянутого поля формы;
  3. добавить визуализацию в поле формы, часто содержащую некоторые данные из сертификата подписавшего (если подпись не выбрана невидимой);
  4. сделать некоторые другие поля формы доступными только для чтения, если подписана пустая подпись для поля с информацией о блокировке поля;
  5. завершить работу с PDF, то есть они устанавливают метаданные как время последнего изменения, а затем записывают готовый PDF в файл или какой-либо байтовый массив;
  6. вычислить значение хеш-функции готового PDF, исключая значение большого заполнителя, но включая все другие изменения, сделанные, как описано выше;
  7. подписать это значение хеша, в результате чего получится контейнер сигнатуры CMS;
  8. и поместите этот контейнер для подписи в большой заполнитель.

Таким образом, в общем случае "оригинальный pdf" больше нельзя извлечь из подписанного PDF-файла, потому что описанные выше изменения могли фундаментально изменить внутреннюю структуру PDF.

Однако есть одно исключение: если эти изменения были применены как инкрементное обновление (в iText lingo: в режиме добавления), обычно можно получить оригинал, отключив это инкрементное обновление.

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

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