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, они:
- добавить поле формы подписи в PDF (если только поле формы подписи не существует и не выбрано для использования в подписи);
- добавить в PDF объект словаря с некоторыми записями, связанными с подписью, в частности с большой записью-заполнителем, в которую в конечном итоге будет вставлен контейнер подписи CMS; этот словарь устанавливается как значение вышеупомянутого поля формы;
- добавить визуализацию в поле формы, часто содержащую некоторые данные из сертификата подписавшего (если подпись не выбрана невидимой);
- сделать некоторые другие поля формы доступными только для чтения, если подписана пустая подпись для поля с информацией о блокировке поля;
- завершить работу с PDF, то есть они устанавливают метаданные как время последнего изменения, а затем записывают готовый PDF в файл или какой-либо байтовый массив;
- вычислить значение хеш-функции готового PDF, исключая значение большого заполнителя, но включая все другие изменения, сделанные, как описано выше;
- подписать это значение хеша, в результате чего получится контейнер сигнатуры CMS;
- и поместите этот контейнер для подписи в большой заполнитель.
Таким образом, в общем случае "оригинальный pdf" больше нельзя извлечь из подписанного PDF-файла, потому что описанные выше изменения могли фундаментально изменить внутреннюю структуру PDF.
Однако есть одно исключение: если эти изменения были применены как инкрементное обновление (в iText lingo: в режиме добавления), обычно можно получить оригинал, отключив это инкрементное обновление.
Для этого нужно просто найти последний маркер конца файла перед подписью и затем удалить его. (На самом деле существует небольшая нестабильность, окончательный маркер конца строки может или не может быть частью исходного PDF.)