Java 如何让PDVisibleSigProperties将3页上的签名写入签名框

Java 如何让PDVisibleSigProperties将3页上的签名写入签名框,java,digital-signature,pdfbox,Java,Digital Signature,Pdfbox,我正在使用pdfbox示例签名CreateVisableSignature,我希望代码将签名图像写入第三页名为“AppliantSignature”的签名字段中 有人能告诉我为什么它会在第一页的左上角写上签名吗 代码如下: public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileN

我正在使用pdfbox示例签名CreateVisableSignature,我希望代码将签名图像写入第三页名为“AppliantSignature”的签名字段中

有人能告诉我为什么它会在第一页的左上角写上签名吗

代码如下:

    public static void main(String[] args) throws KeyStoreException,
        NoSuchAlgorithmException, CertificateException,
        FileNotFoundException, IOException, COSVisitorException,
        SignatureException {

    if (args.length != 4) {
        usage();
        System.exit(1);
    } else {
        File ksFile = new File(args[0]);
        KeyStore keystore = KeyStore.getInstance("PKCS12", provider);
        char[] pin = args[1].toCharArray();
        keystore.load(new FileInputStream(ksFile), pin);
        File document = new File(args[2]);
        CreateVisibleSignature signing = new CreateVisibleSignature(
                keystore, pin.clone());
        String jpgFile = CreateVisibleSignature.convertPngToJpeg( args[3] );
        FileInputStream image = new FileInputStream( jpgFile );
        PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(
                args[2], image, 1);
        visibleSig.xAxis(0).yAxis(0).zoom(-75)
                .signatureFieldName("ApplicantSignature");
        PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
        signatureProperties.signerName("name").signerLocation("location")
                .signatureReason("Security").preferredSize(0).page(3)
                .visualSignEnabled(true).setPdVisibleSignature(visibleSig)
                .buildSignature();
        signing.signPDF(document, signatureProperties);
    }
}
我也尝试过:

    PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(
                args[2], image, 3);
        visibleSig.xAxis(0).yAxis(0).zoom(-75)
                .signatureFieldName("ApplicantSignature");
        PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
        signatureProperties.signerName("name").signerLocation("location")
                .signatureReason("Security").preferredSize(0).page(1)
                .visualSignEnabled(true).setPdVisibleSignature(visibleSig)
                .buildSignature();
我试过:

    PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(
                args[2], image, 3);
        visibleSig.xAxis(0).yAxis(0).zoom(-75)
                .signatureFieldName("ApplicantSignature");
        PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
        signatureProperties.signerName("name").signerLocation("location")
                .signatureReason("Security").preferredSize(0).page(3)
                .visualSignEnabled(true).setPdVisibleSignature(visibleSig)
                .buildSignature();
这是我想在第三页签名的地方。

这就是第一页的内容。

这些是表单中的字段名。

请参见CreateVisibleSignature.java中signPDF()中的这一行(您的问题中未包含这一行,但您提到的PDFBox中的部分示例代码):

删除“/”并在第3页显示签名

重新定位,更改这部分代码

xAxis(0).yAxis(0)
到其他坐标,例如:

xAxis(100).yAxis(715)
现在关于问题,问题中的哪个代码是正确的-最后一个是:

PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(args[2], image, 3);
visibleSig.xAxis(0).yAxis(0).zoom(-75).signatureFieldName("ApplicantSignature");
PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
signatureProperties.signerName("name").signerLocation("location")
    .signatureReason("Security").preferredSize(0).page(3)
    .visualSignEnabled(true).setPdVisibleSignature(visibleSig)
    .buildSignature();

PDVisibleSignDesigner中的3用于选择页面的大小。第二个3是存储页面编号,以备以后使用。这里的页码以1为基础。

根据回答我问题的人给我的页面设置,我发布了一个基于我目前对pdfbox中签名工作原理的了解的答案

首先,我正在使用的现有表单,至少从pdfbox的角度来看,似乎只有一个页面。当我使用adobe DC pro显示坐标时,它只显示第二页中间的坐标。因此,即使我将X,Y坐标设置为100715,签名图像仍显示在第一页的底部,而不是第三页

如果我错了,请纠正我,但我相信pdfbox只允许您对整个文档进行签名,而不允许您对文档中已经存在的单个签名字段进行签名。pdfbox不影响预先存在的签名字段,因为pdfbox似乎无法引用这些字段

如果在adobe dc pro上调出pdf并单击“签名”面板,则可以看到pdf是由pdfbox签名的,但预先存在的签名字段仍然指示需要签名

我猜在这一点上,pdfbox会将其签名添加到预先存在的文档中

我还注意到,pdfbox签名是不可见的,即使“谁”、“位置”、“原因”和日期已设置,并且您在pdfbox签名中放置的图像是在生成的输出pdf中实际可见的唯一内容。如果没有图像,则硬拷贝打印输出不会显示文档已签名


同样,如果我错了,请随时更正。

这是您的表格吗?如果是,则A申请人签名的签名字段的名称为
topmostSubform[0]。Page3[0]。SignatureField1[0]
,而不是
AppliantSignature
,B该表单是AcroForm/XFA混合表单,可能会使事情变得复杂一些。如果不是,请提供您的表单版本,以便分析和复制该问题。@mkl如果他真的想签署该文档,则PDFBox根本无法使用该文档。该文档具有/UR3权限,我们不支持该权限。文档确实得到了签名,但出现了一条错误消息,说明扩展属性丢失。@TilmanHausherr恐怕在创建可见签名的代码中还有更多错误。OP特别使用了
signatureFieldName(“ApplicationSignature”)
希望这将设置签名表单字段的名称(T值)。在代码中,我只看到该值用于在某些签名字典中设置名称(name-value)。此外,我没有看到任何使用现有空签名表单字段的代码;但我认为这正是OP想要做的,在空白签名字段上签名,他假设该字段的名称为
applicationSignature
@tilmanhausher我认为简单地删除UR3使用权签名对OP来说是可以接受的。不过,上面提到的问题可能是一个阻碍。@mkl我不会碰那个签名代码,除了小的错误修复和重构,这对我来说是一个真正的迷宫:-(Denis:可能在JIRA中打开一个问题并附加该文件。但不能保证它会很快修复,一些错误会在一小时内修复,但我也看到了一个简单的问题,花了10年时间。感谢您和mkl的所有评论。我对其他页面参数有一个问题:我应该为PDVisibleSignDesigner visibleSig=new PDVi使用什么值sibleSignDesigner(args[2],image,3);。我有3。我应该为signatureProperties使用什么值。signerName(“名称”)。signerLocation(“位置”)。signatureReason(“安全”)。preferredSize(0)。page(3)。visualSignEnabled(true)。setPdVisibleSignature(visibleSig)。buildSignature();我也有3个。@DenisMP两者都使用3。第一个(PDVisibleSignDesigner)是决定页面大小。第二个是页码。我会改进我的答案。谢谢Tilman。我将根据我学到的内容发布一个答案。请随意评论。A如果你没有解决方案,只是一份临时报告,请编辑你的问题并将信息附加在那里。答案是为了解决问题s、 B“我认为pdfbox只允许您对整个文档进行签名”-严格来说,PDF签名始终对整个文档版本进行签名。这与真正的XFA签名不同,但XFA规范不是PDF标准的一部分。C“不是文档中已经存在的单个签名字段”-事实上,用于创建可见PDF签名的PDFBox代码看起来确实忽略了现有的签名字段。但是签名字段仅用于签名的位置和可视化,下面的数字签名仍然会对整个版本进行签名。D“我也注意到
PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(args[2], image, 3);
visibleSig.xAxis(0).yAxis(0).zoom(-75).signatureFieldName("ApplicantSignature");
PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();
signatureProperties.signerName("name").signerLocation("location")
    .signatureReason("Security").preferredSize(0).page(3)
    .visualSignEnabled(true).setPdVisibleSignature(visibleSig)
    .buildSignature();