Java 为什么使用iText 7.1.11的某些PDF文档中看不到数字签名?

Java 为什么使用iText 7.1.11的某些PDF文档中看不到数字签名?,java,pdf,itext,itext7,Java,Pdf,Itext,Itext7,我的项目使用数字证书对PDF文档进行数字签名,并在文档左下角显示签名。它一直工作良好,直到现在,有一些文档是数字签名的,但它没有显示,尽管人们认识到它所在的矩形是可见的。如果有人能帮忙,我留下一个处理数字签名的片段。 我在PDF文档中留下了数字签名的截图,我在文档的左下角显示了它 示例 在本文中,我分享了该问题的示例pdf文档,如果没有它,我将在下面详细介绍它们: ok\u unsigned.pdf文件:这是一个文件,当通过我的项目时,它的签名良好,成为ok\u signed.pdf文件(这是

我的项目使用数字证书对PDF文档进行数字签名,并在文档左下角显示签名。它一直工作良好,直到现在,有一些文档是数字签名的,但它没有显示,尽管人们认识到它所在的矩形是可见的。如果有人能帮忙,我留下一个处理数字签名的片段。 我在PDF文档中留下了数字签名的截图,我在文档的左下角显示了它

示例

在本文中,我分享了该问题的示例pdf文档,如果没有它,我将在下面详细介绍它们:

  • ok\u unsigned.pdf
    文件:这是一个文件,当通过我的项目时,它的签名良好,成为
    ok\u signed.pdf
    文件(这是目前为止的标准)
  • ok\u signed.pdf
    文件:它是数字签名的
    ok\u unsigned.pdf
    文件,这是一个成功的案例
  • bad_unsigned.pdf
    文件:这是一个空白文档,当对其进行数字签名(
    bad_signed.pdf
    )时,会出现问题
  • bad_signed.pdf
    文件:这是一个有问题的文档,经过数字签名,但看不到签名字段
代码

        try {
            BouncyCastleProvider providerBC = new BouncyCastleProvider();
            Security.addProvider(providerBC);

            KeyStore ks = KeyStore.getInstance("pkcs12");
            ks.load(new FileInputStream(keystore), password);
            String alias = ks.aliases().nextElement();
            Certificate[] chain = ks.getCertificateChain(alias);
            PrivateKey pk = (PrivateKey) ks.getKey(alias, password);

            PdfReader reader = new PdfReader(src);
            FileOutputStream fos = new FileOutputStream(new File(dest));
            PdfSigner signer = new PdfSigner(reader, fos, new StampingProperties());
            Rectangle rect = new Rectangle(10, 10, 150, 50);
            PdfSignatureAppearance appearance = signer.getSignatureAppearance();
            
            appearance.setPageRect(rect)
                    .setCertificate(chain[0])
                    .setReasonCaption("")
                    .setLocationCaption("")
                    .setSignatureCreator("SignerJAGC - iText 7.1.11")
                    .setPageNumber(1);
            signer.setFieldName("Banca en Línea - Envío de Documentos");
            signer.setSignDate(new GregorianCalendar());
            signer.setCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED);

            IExternalDigest digest = new BouncyCastleDigest();
            IExternalSignature signature = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, providerBC.getName());

            signer.signDetached(digest, signature, chain, null, null, null, 0, SUBFILTER);
            System.out.println("SIGNED");
        } catch (Exception ex) {
            System.err.println(ex.getMessage());
        }
    }```

正如@mkl所说,您的坐标可能位于页面可见区域之外,因为并非所有PDF页面的左下角都位于(0,0)

尝试创建签名矩形,如下所示:

Rectangle rect = new Rectangle(
    yourPageCropBoxLowerLeftX + 10, 
    yourPageCropBoxLowerLeftY + 10, 
    yourPageCropBoxLowerLeftX + 10 + yourSignatureWidth, 
    yourPageCropBoxLowerLeftY + 10 + yourSignatureHeight);

您只需看看如何读取页面的裁剪框坐标,即左下角,因为我不熟悉iText API。

正如@mkl所说,您的坐标可能位于页面可见区域之外,因为并非所有PDF页面的左下角都位于(0,0)

尝试创建签名矩形,如下所示:

Rectangle rect = new Rectangle(
    yourPageCropBoxLowerLeftX + 10, 
    yourPageCropBoxLowerLeftY + 10, 
    yourPageCropBoxLowerLeftX + 10 + yourSignatureWidth, 
    yourPageCropBoxLowerLeftY + 10 + yourSignatureHeight);

您只需看看如何读取页面的裁剪框坐标(左下角),因为我不熟悉iText API。

请共享一个由您的代码签名的PDF示例,其中没有签名。显而易见的原因可能是您给出的坐标不在可见页面区域(每个页面可能有自己的坐标系,左下角通常只是原点),或者PDF是XFA表单。但这也可能是由其他原因造成的。抱歉@mkl,我不能共享任何PDF文档,因为我的雇佣合同禁止共享。坐标不是问题,因为如果你看到我的片段,我只能从点(0,0)处移动10个像素(X和Y)。虽然我不能在这里共享任何PDF文档,但我留下了一个签名文档的屏幕截图。如果没有PDF说明问题,我无法比我的原始注释进一步分析。@mkl,我将尝试了解如何共享具有该特性的PDF文档。谢谢您的帮助。@mkl,在这篇文章中,我已经与您分享了有问题的pdf文档示例,如果没有,我将在示例部分的问题中详细介绍这些文档:请分享一个由您的代码签名的pdf示例,签名没有出现在该示例上。显而易见的原因可能是您给出的坐标不在可见页面区域(每个页面可能有自己的坐标系,左下角通常只是原点),或者PDF是XFA表单。但这也可能是由其他原因造成的。抱歉@mkl,我不能共享任何PDF文档,因为我的雇佣合同禁止共享。坐标不是问题,因为如果你看到我的片段,我只能从点(0,0)处移动10个像素(X和Y)。虽然我不能在这里共享任何PDF文档,但我留下了一个签名文档的屏幕截图。如果没有PDF说明问题,我无法比我的原始注释进一步分析。@mkl,我将尝试了解如何共享具有该特性的PDF文档。谢谢你的帮助。@mkl,在这篇文章中,我与本期分享了pdf文档示例,如果没有,我将在示例部分的问题中详细介绍它们:我认为它们不是坐标,因为pdf读者告诉我该区域有“某物”(数字签名)。谢谢你的评论,我会记住它,我会记住它来回顾一切。正如@mkl猜测的,你的页面裁剪框左下角坐标是(0432),而你的签名位于(10,10),因此它位于页面可见区域之外。非常感谢@iPDFdev的帮助。我必须使用页面的CropBox坐标。我不认为它们是坐标,因为PDF阅读器告诉我在那个区域有“东西”(数字签名)。谢谢你的评论,我会记住它,我会记住它来回顾一切。正如@mkl猜测的,你的页面裁剪框左下角坐标是(0432),而你的签名位于(10,10),因此它位于页面可见区域之外。非常感谢@iPDFdev的帮助。我必须使用页面的CropBox坐标。