PDFBox Mehrfachsignatur mit ungültiger Java-Signatur
Ich hatte einige Anforderungen an den PDF-Multi-Signing-Workflow. In diesem PDF wird mehrmals signiert, ohne dass Änderungen am Dokument vorgenommen werden. Angenommen, zwei oder mehr Personen können dasselbe Dokument signieren. Ich versuche, die Signaturen im PDF zweimal hinzuzufügen, aber nach dem zweiten Signieren des PDF wird die erste Signatur ungültig. Ich habe PDFBox Java API für die Erstellung von PDF-Signaturen verwendet.
Schritte zur PDF-Erstellung:
- Erstelltes PDF durch Hinzufügen leerer Signaturfeldnamen: [email protected] und [email protected] unter Verwendung des ursprünglichen hello.pdf-Ausgangsdateinamens hello_tag.pdf Ausführungsprogramm> TagPDFSignatureFields.java
- Beim ersten Signieren durch Abrufen des Signaturfelds [email protected] aus der Datei hello_tag.pdf lautet der Dateiname hello_signed.pdf. Führen Sie das Programm> SignAndIdentifySignatureFields.java aus
- Beim zweiten Signieren durch Abrufen des Signaturfelds [email protected] aus der Datei hello_signed.pdf lautet der Dateiname hello_singed2.pdf. Führen Sie das Programm> Sign2.java aus
Im 2. Schritt wird das PDF ordnungsgemäß signiert, aber nach dem 3. Schritt wird die signierte Version im 2. Schritt ungültig und die Signatur im 3. Schritt wird im Acrobat Reader als in Ordnung angezeigt.
Hier finden Sie den Link Java-Quellcode und das PDF-Beispiel als Referenz. Google Laufwerkslink pdf_multi_signs_pdfbox_java
Jede Hilfe wäre dankbar.
Antworten
Kurz gesagt, es gibt eine Reihe von Problemen in Ihrem Code. Das Problem, das dazu führt, dass Adobe Reader Ihre erste Signatur nach dem Hinzufügen einer zweiten Signatur als bereits ungültig markiert, befindet sich in Ihrem Vorbereitungsschritt, TagPDFSignatureFields
in dem Sie einen ungültigen doppelten Seitenbaumeintrag erstellen. Die anderen Probleme sollten ebenfalls behoben werden, obwohl sich Adobe Reader derzeit nicht beschwert.
Die Probleme im Detail ...
Doppelte Seiteneingabe
In TagPDFSignatureFields
Ihrer Methode addEmptySignField
beginnt wie folgt:
private void addEmptySignField(String[] args) throws Exception, IOException {
// Create a new document with an empty page.
try (PDDocument document = PDDocument.load(new File(args[0]));)
{
PDPage page = document.getPage(0);
document.addPage(page);
Hier rufen Sie die erste Seite von ab document
und fügen diese Seite sofort document
wieder hinzu. Dadurch hello_tag.pdf
sieht der Seitenstammbaumknoten in Ihrer Datei folgendermaßen aus:
2 0 obj
<<
/Type /Pages
/Count 2
/Kids [6 0 R 6 0 R]
>>
endobj
Das heißt, der Seitenbaum enthält zweimal dasselbe Seitenobjekt, das Adobe Reader nicht akzeptiert, sondern unter der Haube repariert. Bei den signierten Dokumenten warnt Adobe Reader vage davor:

In aktuellen Versionen (z. B. 2020.013.20066) markiert Adobe Reader in der doppelt signierten Datei sogar die erste Signatur als fehlerhaft. In früheren Versionen (z. B. 2019.012.20040) war dies nicht der Fall. Dies ist wahrscheinlich ein Effekt der Verhärtung des Validierungscodes nach Veröffentlichung der Schattenangriffe.
Nebenbei: Wenn Sie in einer Situation sind, in der die Bearbeitung eines signierten Dokuments (Ausfüllen von Formularen, erneutes Signieren, ...) die alten Signaturen beschädigt, überprüfen Sie immer auch, ob das Originaldokument möglicherweise bereits Probleme aufweist. Die Prüfung, ob Änderungen an einem signierten Dokument zulässig sind, ist sehr empfindlich gegenüber Fehlern, die ansonsten unter der Haube behoben werden und daher nicht sichtbar sind.
Ungültige Teilfeldnamen
Sie verwenden E-Mail-Adressen als Feldnamen [email protected]
und [email protected]
im Fall Ihres Beispiels:
signatureField.setPartialName("[email protected]");
...
signatureField1.setPartialName("[email protected]");
( TagPDFSignatureFields
Methode addEmptySignField
)
Diese Teilfeldnamen sind ungültig. Teilfeldnamen dürfen keine Punktzeichen ('.') Enthalten.
PDFBox wird in zukünftigen Versionen versuchen, dies zu verhindern, siehe PDFBOX-5028 .
Festlegen der Standardressourcen und der Standarddarstellungen beim Signieren
Während des Signierens legen Sie die Standardressourcen und das Standardbild des AcroForm- Wörterbuchs fest:
acroForm.setDefaultResources(resources);
...
acroForm.setDefaultAppearance(defaultAppearanceString);
( SignAndIdentifySignatureFields
und Sign2
Methode addEmptySignField
)
An sich ist dies keine schlechte Sache, aber Vorsicht, wenn Sie dies für eine zuvor signierte Datei tun, die bereits solche Einträge enthält, und diese auf andere Werte als zuvor setzen, kann dies die frühere Signatur ungültig machen . Siehe das hier beantwortete Problem .
PDF-Version ohne Notwendigkeit einstellen
Sie versuchen, die beanspruchte PDF-Version des Dokuments zu ändern:
document.setVersion(1.0f);
( SignAndIdentifySignatureFields
Methode addEmptySignField
)
document.setVersion(2.0f);
( Sign2
Methode addEmptySignField
)
Die erste Anweisung wird ignoriert, da für das Dokument selbst bereits eine Version von mindestens 1,5 erforderlich ist. Die zweite Anweisung setzt die PDF-Version des Dokuments jedoch auf 2.0, was bei älteren Viewern zu Problemen führen kann.
...
Es gibt sehr wahrscheinlich mehr Probleme. Ich habe diese Probleme erst entdeckt, bevor ich erkannte, dass das Beheben des einzigen ersten Problems, des doppelten Seiteneintrags, ausreichte, um die erste Signatur zu heilen ...