Gewusst wie: zuordnen einer vorherigen Unterschrift in eine neue Signatur-Feld

Habe ich eine signierte PDF-Datei. Ich möchte zeigen, dass diese Signatur in das Dokument. Ich kann nur hinzufügen, ein neues Unterschriftsfeld, auf diese Weise:

Stamper.addSignature("My Signature", 1, 20f, 10f, 100f, 100f);

Aber ich kann nicht einen Weg finden, verbinden es mit der Signatur, ist bereits in dem Dokument.

Wie kann ich die zuordnen?

  • Ich habe eine signierte PDF-Datei. Ich möchte zeigen, dass diese Signatur in das Dokument. – wenn die PDF-Datei signiert ist, seine Signatur schon zeigt, nicht wahr? Ich verstehe nicht, was Sie versuchen zu erreichen.
  • Hi, ist Das Zeichen gezeigt, wenn Sie öffnen Sie die Taktart-Panel, aber ich möchte, dass die Zeichen wäre, zeigte sich in den Dokument ausfüllen eines Feldes. So etwas wie dieses: [link(]isunshare.com/blog/wp-content/uploads/2015/02/…)
InformationsquelleAutor user5918204 | 2016-05-04



One Reply
  1. 5

    Den OP will, befestigen Sie ein Dokument Signatur Visualisierung einer vorhandenen Signatur.

    Erste von allen, das ist offensichtlich nicht zulässig, wenn Ihre Dokumente wurde zertifiziert mit änderungen nicht gestattet

    Ganz überraschend, obwohl, es scheint, darf für unterzeichnet, aber nicht beglaubigte Dokumente (die die Beispiel-Datei ist, die ich gearbeitet habe).

    In der Tat, es sei denn, ein Dokument wurde zertifiziert mit änderungen nicht gestattet, Sie sind immer erlaubt füllen Sie die Formulare und (außer für Dokumente zertifiziert mit dem ausfüllen von Formularen und digitale Signaturen erlaubt) sogar ändern von Anmerkungen, vgl. diese Antwort für eine übersicht.

    Als PDF-Signaturen sind Formularfeld-Werte und Visualisierung von form-Felder sind spezielle Anmerkungen ändern der Signatur-Visualisierungen ist zulässig, da form-fill-in-oder zumindest als Anmerkung Modifikation.

    Tut es in iText 5

    Der OP versucht dies umzusetzen, indem Sie eine neue Signatur-Feld:

    Stamper.addSignature("My Signature", 1, 20f, 10f, 100f, 100f);

    Diese nicht helfen, aber, da hat man eine änderung der bestehenden Signatur-Feld, nicht eine neue zu erstellen.

    Mithilfe von iText 5.x dies geschieht über die generische form field manipulation API:

    PdfReader pdfReader = new PdfReader(resource);
    PdfStamper pdfStamper = new PdfStamper(pdfReader, result, '\0', true);
    
    AcroFields acroFields = pdfStamper.getAcroFields();
    for (String signatureName : acroFields.getSignatureNames())
    {
        Item field = acroFields.getFieldItem(signatureName);
        field.writeToAll(PdfName.RECT, new PdfArray(new int[]{100,100,200,200}), Item.WRITE_WIDGET);
        field.markUsed(acroFields, Item.WRITE_WIDGET);
    
        PdfAppearance appearance = PdfAppearance.createAppearance(pdfStamper.getWriter(), 100, 100);
        appearance.setColorStroke(BaseColor.RED);
        appearance.moveTo(0, 0);
        appearance.lineTo(99, 99);
        appearance.moveTo(0, 99);
        appearance.lineTo(99, 0);
        appearance.stroke();
    
        PdfDictionary appDict = new PdfDictionary();
        appDict.put(PdfName.N, appearance.getIndirectReference());
        field.writeToAll(PdfName.AP, appDict, Item.WRITE_WIDGET);
    }
    
    pdfStamper.close();

    (ChangeSignatureAppearance.java Methode testChangeAppearances)

    Dieser code erstellt eine neue Signatur Aussehen für jeden integrierte PDF-Signatur, in diesem Fall ein rotes Kreuz liegt bei 100, 100 und Größe 100×100, aber können Sie jede Erscheinung, die Sie mögen es.

    Vorsicht: dieser code übernimmt die unsichtbare Signatur in Zusammenhang mit manchen Dokument-Seite. Für unsichtbare Signaturen, die nicht im Zusammenhang mit einer Seite noch ein Verein aufgebaut haben. Dies ist wahrscheinlich könnte sich herausstellen, dass eine änderung, die nicht erlaubt, zumindest ist es keine bloße form, fill-in mehr, weil auch die form, die Struktur ist verändert, nicht nur seine Einträge.


    Die OP in einem Kommentar

    Aber ich würde gerne rufen Sie den Namen, das Zeichen und schreiben es statt einem roten Kreuz

    Dafür müssen lediglich zu geringfügig ändern Sie den obigen code:

    PdfReader pdfReader = new PdfReader(resource);
    PdfStamper pdfStamper = new PdfStamper(pdfReader, result, '\0', true);
    
    AcroFields acroFields = pdfStamper.getAcroFields();
    for (String signatureName : acroFields.getSignatureNames())
    {
        PdfPKCS7 pkcs7 = acroFields.verifySignature(signatureName);
        X509Certificate signerCert = (X509Certificate) pkcs7.getSigningCertificate();
        String signerName = CertificateInfo.getSubjectFields(signerCert).getField("CN");
    
        Item field = acroFields.getFieldItem(signatureName);
        field.writeToAll(PdfName.RECT, new PdfArray(new int[]{100,100,200,200}), Item.WRITE_WIDGET);
        field.markUsed(acroFields, Item.WRITE_WIDGET);
    
        PdfAppearance appearance = PdfAppearance.createAppearance(pdfStamper.getWriter(), 100, 100);
        ColumnText columnText = new ColumnText(appearance);
        Chunk chunk = new Chunk();
        chunk.setSkew(0, 12);
        chunk.append("Signed by:");
        columnText.addElement(new Paragraph(chunk));
        chunk = new Chunk();
        chunk.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, 1, BaseColor.BLACK);
        chunk.append(signerName);
        columnText.addElement(new Paragraph(chunk));
        columnText.setSimpleColumn(0, 0, 100, 100);
        columnText.go();
    
        PdfDictionary appDict = new PdfDictionary();
        appDict.put(PdfName.N, appearance.getIndirectReference());
        field.writeToAll(PdfName.AP, appDict, Item.WRITE_WIDGET);
    }
    
    pdfStamper.close();

    (ChangeSignatureAppearance.java Methode testChangeAppearancesWithName)

    Im Fall der Probe-Dokument BouncyCastle registriert werden als security-Anbieter.

    Und die Warnung von oben gilt weiterhin.

    Tut es in iText 7

    Als iText 7 wurde kürzlich veröffentlicht, der obige code portiert werden können dies wie folgt:

    try (   PdfReader pdfReader = new PdfReader(resource);
            PdfWriter pdfWriter = new PdfWriter(result);
            PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().useAppendMode()))
    {
        SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
        PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDocument, false);
    
        for (String name : signatureUtil.getSignatureNames())
        {
            PdfFormField field = acroForm.getField(name);
            field.setModified();
            for (PdfWidgetAnnotation pdfWidgetAnnotation : field.getWidgets())
            {
                pdfWidgetAnnotation.setRectangle(new PdfArray(new int[]{100, 100, 200, 200}));
    
                PdfFormXObject form = new PdfFormXObject(new Rectangle(100, 100));
                PdfCanvas canvas = new PdfCanvas(form, pdfDocument);
                canvas.setStrokeColor(Color.RED);
                canvas.moveTo(0, 0);
                canvas.lineTo(99, 99);
                canvas.moveTo(0, 99);
                canvas.lineTo(99, 0);
                canvas.stroke();
    
                pdfWidgetAnnotation.setNormalAppearance(form.getPdfObject());
            }
        }
    }

    (ChangeSignatureAppearance.java Methode testChangeAppearances)

    Dieser code erfordert die iText 7 Artefakte kernel, forms, und sign.

    Dieselbe Warnung wie im Fall der iText-5 code oben gilt:

    Vorsicht: dieser code übernimmt die unsichtbare Signatur in Zusammenhang mit manchen Dokument-Seite.


    Die Variante mit den Namen des Antragstellers sieht wie folgt aus:

    try (   PdfReader pdfReader = new PdfReader(resource);
            PdfWriter pdfWriter = new PdfWriter(result);
            PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().useAppendMode()))
    {
        SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
        PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDocument, false);
    
        for (String name : signatureUtil.getSignatureNames())
        {
            PdfPKCS7 pkcs7 = signatureUtil.verifySignature(name);
            X509Certificate signerCert = (X509Certificate) pkcs7.getSigningCertificate();
            String signerName = CertificateInfo.getSubjectFields(signerCert).getField("CN");
            PdfFormField field = acroForm.getField(name);
            field.setModified();
            for (PdfWidgetAnnotation pdfWidgetAnnotation : field.getWidgets())
            {
                pdfWidgetAnnotation.setRectangle(new PdfArray(new int[]{100, 100, 200, 200}));
    
                PdfFormXObject form = new PdfFormXObject(new Rectangle(100, 100));
                Canvas canvas = new Canvas(form, pdfDocument);
                canvas.add(new Paragraph().setItalic().add("Signed by:"));
                canvas.add(new Paragraph().setBold().add(signerName));
    
                pdfWidgetAnnotation.setNormalAppearance(form.getPdfObject());
            }
        }
    }

    (ChangeSignatureAppearance.java Methode testChangeAppearancesWithName)

    Dieser code zusätzlich benutzt die iText 7 Artefakt layout. Außerdem, im Falle des Beispiel-Dokument BouncyCastle registriert werden als security-Anbieter, ebenso wie für die iText-5 code oben.

    Wieder die Warnung von oben gilt weiterhin.

    Es bei der Suche in Adobe Acrobat Reader DC

    Getestet habe ich diese in Adobe Acrobat Reader DC mit einem unsichtbar unterzeichnet leeres Dokument LEER-unterzeichnet.pdf:

    Gewusst wie: zuordnen einer vorherigen Unterschrift in eine neue Signatur-Feld

    Manipuliert haben, die Datei mit dem code oben, ich habe:

    Gewusst wie: zuordnen einer vorherigen Unterschrift in eine neue Signatur-Feld

    Die Warnung bezüglich nicht signierter änderungen korrekt ist, aber nach der Anmeldung wieder, auch die Warnung verschwindet:

    Gewusst wie: zuordnen einer vorherigen Unterschrift in eine neue Signatur-Feld


    Die Variante mit signer name sieht wie folgt aus:

    Gewusst wie: zuordnen einer vorherigen Unterschrift in eine neue Signatur-Feld

    Anhang: Mehrere Auftritte mit einer Unterschrift

    Der OP fragte in einem Kommentar

    Diese Methode nur stampt es in der ersten Seite des Dokuments. Wie kann ich Stempel es in alle Seiten des Dokuments ?

    Den oben genannten Methoden im Allgemeinen eigentlich nicht der Stempel auf der ersten Seite aber auf der Seite mit der Unterschrift. Unsichtbare Signaturen sind oft verbunden mit der ersten Seite, obwohl, ist es verständlich, warum es schien so.

    Außerdem mehrere Auftritte eines „single signature“ – Feld sind nicht universell unterstützt (zwar eigentlich nicht verboten nach ISO 32000-1), und Sie werden verboten durch die kommende ISO 32000-2. Somit ist es nicht die beste Idee, diesen Weg zu gehen.

    Wenn es keine Möglichkeit um ihn herum, obwohl, können Sie versuchen, so etwas wie dies in iText 7:

    try (   PdfReader pdfReader = new PdfReader(resource);
            PdfWriter pdfWriter = new PdfWriter(result);
            PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().useAppendMode()))
    {
        SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
        PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDocument, false);
    
        for (String name : signatureUtil.getSignatureNames())
        {
            PdfPKCS7 pkcs7 = signatureUtil.verifySignature(name);
            X509Certificate signerCert = (X509Certificate) pkcs7.getSigningCertificate();
            String signerName = CertificateInfo.getSubjectFields(signerCert).getField("CN");
            PdfFormField field = acroForm.getField(name);
            field.setModified();
    
            Rectangle rectangle = new Rectangle(100, 100);
            PdfFormXObject form = new PdfFormXObject(rectangle);
            Canvas canvas = new Canvas(form, pdfDocument);
            canvas.add(new Paragraph().setItalic().add("Signed by:"));
            canvas.add(new Paragraph().setBold().add(signerName));
    
            for (PdfWidgetAnnotation pdfWidgetAnnotation : field.getWidgets())
            {
                PdfDictionary pageObject = pdfWidgetAnnotation.getPageObject();
                PdfPage page = pdfDocument.getPage(pageObject);
                page.removeAnnotation(pdfWidgetAnnotation);
    
                pdfWidgetAnnotation.releaseFormFieldFromWidgetAnnotation();
            }
    
            for (int pageNumber = 1; pageNumber <= pdfDocument.getNumberOfPages(); pageNumber++)
            {
                PdfPage pdfPage = pdfDocument.getPage(pageNumber);
                PdfWidgetAnnotation pdfWidgetAnnotation = new PdfWidgetAnnotation(rectangle);
                pdfWidgetAnnotation.setNormalAppearance(form.getPdfObject());
                pdfWidgetAnnotation.setPage(pdfPage);
                field.addKid(pdfWidgetAnnotation);
                pdfPage.addAnnotation(pdfWidgetAnnotation);
            }
        }
    }

    (ChangeSignatureAppearance.java Methode testChangeAppearancesWithNameAllPages)

    Dies entfernt zunächst alle vorhandenen Anmerkungen in das Feld Signatur, und dann fügt neue hinzu, um alle Felder.

    Genau wie oben, dies wird eine Warnung über unsignierte änderungen angezeigt, die wahr ist, nachdem alle.

    Nebenbei, wenn man ein signiertes Dokument, das mit einer Visualisierung auf der einen Seite und änderungen der code oben nicht zum entfernen der ursprünglichen Beschriftung, die kann man einfach durch hinzufügen von Kopien der annotation auf allen Seiten, und der aktuelle Adobe Acrobat Reader gar nicht angezeigt, eine Warnung! Der Leser code für die überprüfung auf änderungen in einem unterzeichneten Dokument ist seltsam in der Tat…

    • Danke mkl! Es funktioniert. Aber ich würde gerne rufen Sie den Namen, das Zeichen und schreiben es statt einem roten Kreuz?
    • der name des Zeichens – du meinst das Thema aus der signer-Zertifikat? Sollte kein problem sein, sollte es nicht?
    • Wenn ich Schreibe, die signatureName zeigt „Signature1“. Ich möchte der text erscheint nach der „Signiert“ (über Signatur-Dienst in Ihrem Beispiel), aber ich weiß nicht, Holen Sie sich diesen Wert.Danke mkl
    • Ich habe versucht, dies zu tun, aber es nicht funktioniert: in Der zweiten Zeile (acroFields.verifySignature() wirft eine exception: java.lang.NoClassDefFoundError. Ich weiß nicht, ob dies ist der Weg, es zu bekommen: Item-Feld = acroFields.getFieldItem(signatureName); PdfPKCS7 pk = acroFields.verifySignature(signatureName); Aussehen.showText(„Betreff:“ + CertificateInfo.getSubjectFields(pk.getSigningCertificate())); Optik.endText();
    • acroFields.verifySignature() wirft eine exception: java.lang.NoClassDefFoundError – bitte sehen Sie auch in Ausnahme-Meldung, nicht nur bei der exception-Klasse. Die Meldung wird Ihnen sagen, welche Klasse. Ich würde davon ausgehen, BouncyCastle nicht in Ordnung ist. Übrigens, ich habe gerade iText 7 code hinzufügen des Unterzeichners gemeinsamen Namen; ist alles ein bisschen aufgeräumter dort…
    • Ja. Ich habe hinzufügen in das Projekt Java built path der bcprov-jdk15on-1.47.jar und bcmail-jdk15on-154 mit itext-5.5.9. Jedoch bekomme ich die nächste Fehlermeldung: Exception in thread „main“ java.lang.NoClassDefFoundError: org/bouncycastle/tsp/TimeStampTokenInfo an com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2420).
    • bcprov-jdk15on-1.47.jar und bcmail-jdk15on-154a BouncyCastle Artefakt-Versionen müssen übereinstimmen. b iText benötigt bcprov und bcpkix aber nicht bcmail. c iText 5.5.9 erfordert BouncyCastle Artefakte in der version 1.49. Vgl. die iText pom-Datei.
    • Jetzt im refrencing bcpkix-jdk15on-1.49-und bcprov-jdk15on-1.49. Aber in diesem Punkt: PdfPKCS7 pkcs7 = acroFields.verifySignature(signatureName); Seine werfen diese exception Exception in thread „main“ ExceptionConverter: java.Sicherheit.InvalidKeyException: Schlüssel darf nicht null sein
    • Das ist, warum ich schrieb BouncyCastle registriert werden als Sicherheits-provider – ohne, dass ich die gleiche Ausnahme.
    • Es funktioniert. Danke!!!
    • Super!!! In diesem Fall markieren Sie bitte die Antwort als akzeptiert (klicken Sie auf das Häkchen in der oberen linken.)
    • Eine andere Frage. Bei dieser Methode werden nur stampt es in der ersten Seite des Dokuments. Wie kann ich Stempel es in alle Seiten des Dokuments ?
    • Wie kann ich Stempel es auf allen Seiten im Dokument an – es ist Zwar möglich, Erscheinungsbilder auf allen Seiten für die PDF-1.x -, PDF-2.x wird dies verbieten. Daher sollten Sie überlegen, ob Sie wirklich wollen, dass, wie es machen wird Ihr Antrag veraltet ist, bevor es noch veröffentlicht wird.
    • Ich fügte hinzu, ein „Anhang: Mehrere Auftritte der Unterschrift“ zur Antwort.
    • „man kann einfach durch hinzufügen von Kopien der annotation auf allen Seiten, und der aktuelle Adobe Acrobat Reader gar nicht angezeigt, eine Warnung!“ – Dies hat sich geändert, mittlerweile Adobe Reader wurde gestartet mit einem „Formular-Felder mit Änderungen der Eigenschaft“ Warnung.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.