0

我正在将 PDF 转换为 PDF/A。我已经通过付费 PDFTools 库进行了此转换,我将转换结果放在此页面上,该页面负责验证它是否符合 PDA/A 标准https://www.pdf-online.com/osa/ validate.aspx 验证表明它符合标准。转换后,PDF 将使用 Itext 5.5.5 库进行签名,但是,如果我再次使用验证器,则 PDF/A 标准不再有效。验证器上显示的错误如下:

The name object must be UTF-8 encoded.

A device-specific color space (DeviceGray) without an appropriate output intent is used.

The font Helvetica must be embedded.

The document does not conform to the requested standard.

签名时,将有关数字签名的信息(例如印章)添加到文档中;正是由于这个原因,它不再符合标准。从消除这些错误开始,我已经使用以下代码消除了 Helvetica 字体错误:

String path = Sign.class.getResource("helvetica.ttf").toExternalForm();
FontFactory.register(path);
BaseFont base = BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(base);
appearance.setLayer2Font(font);

但是,我并没有消除这两个错误:

The name object must be UTF-8 encoded.

A device-specific color space (DeviceGray) without an appropriate output intent is used.

The document does not conform to the requested standard.

颜色空间的错误,我尝试使用以下代码消除它,但根本没有帮助,因为当我再次进行验证时它会不断收到错误。

path = Sign.class.getResource("sRGBColorSpaceProfile.icm").toExternalForm();
ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream(path));
stamper.getWriter().setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);

我希望您能帮助我了解如何消除错误以使其符合 PDF/A 标准,或者是否有其他替代方法可以让我转换为 PDF/A,然后使用 Itext 5.5.5 库对其进行签名。

我很感激你能给我的帮助。谢谢

更新

这是我用来使用 Itext 5.5.5 库签署文档的代码。

String pkcs11Config = "name=NAME" + "\n" + "library=PATH";
ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11Config.getBytes());
Provider pkcs11Provider = new sun.security.pkcs11.SunPKCS11(configStream);
Security.addProvider(pkcs11Provider);
KeyStore ks = KeyStore.getInstance("PKCS11");
ks.load(null, password);

PdfReader reader = new PdfReader(pdfInput);
FileOutputStream os = new FileOutputStream(pdfOutputTemp);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);

PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
String path = Sign.class.getResource("helvetica.ttf").toExternalForm();
FontFactory.register(path);
BaseFont base = BaseFont.createFont(path, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(base);
appearance.setLayer2Font(font);

path = Sign.class.getResource("sRGBColorSpaceProfile.icm").toExternalForm();
ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream(path));
stamper.getWriter().setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);

        ...

PrivateKey key = (PrivateKey) ks.getKey(alias, pass);
ExternalSignature es = new PrivateKeySignature(key, DigestAlgorithms.SHA256, null);
ExternalDigest digest = new BouncyCastleDigest();

MakeSignature.signDetached(appearance, digest, es, chain, crlList, null, tsc, 0, CryptoStandard.CADES);

更新 2

我尝试将 PdfStamper 更改为 PdfAStamper,但是当我尝试签署文档时,它返回以下错误:

com.itextpdf.text.pdf.PdfAConformanceException: Annotation of type /Widget should have Contents key.
    at com.itextpdf.text.pdf.internal.PdfA2Checker.checkAnnotation(PdfA2Checker.java:707)
    at com.itextpdf.text.pdf.internal.PdfAChecker.checkPdfAConformance(PdfAChecker.java:219)
    at com.itextpdf.text.pdf.internal.PdfAConformanceImp.checkPdfIsoConformance(PdfAConformanceImp.java:71)
    at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3480)
    at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3476)
    at com.itextpdf.text.pdf.PdfAnnotation.toPdf(PdfAnnotation.java:989)
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.addToObjStm(PdfWriter.java:292)
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:382)
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:373)
    at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:369)
    at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:843)
    at com.itextpdf.text.pdf.PdfStamperImp.addAnnotation(PdfStamperImp.java:1395)
    at com.itextpdf.text.pdf.PdfStamperImp.addAnnotation(PdfStamperImp.java:1408)
    at com.itextpdf.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:1285)
    at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:243)

更新 3

我将 itext 库从 5.5.5 更新到 5.5.13.1,效果更好。

如果我使用 PdfStamper,我可以签署文档,但是当我使用 PDF/A 验证器时,它会返回以下错误:

Validating file "DOCUMENT.pdf" for conformance level pdfa-2a

     A device-specific color space (DeviceGray) without an appropriate output intent is used.

     The document does not conform to the requested standard.

The document contains device-specific color spaces.

The document does not conform to the PDF/A-2a standard.

Done.

错误提示:“名称对象必须是 UTF-8 编码的。” 不再出现。

另外,我尝试使用 PdfStamper。当我尝试签署文件时,它会返回与以前不同的异常。这是新的例外:

com.itextpdf.text.pdf.PdfAConformanceException: DeviceGray shall only be used if a device independent DefaultGray colour space has been set when the DeviceGray colour space is used, or if a PDF/A OutputIntent is present.
    at com.itextpdf.text.pdf.internal.PdfA2Checker.close(PdfA2Checker.java:829)
    at com.itextpdf.text.pdf.PdfAStamperImp.close(PdfAStamperImp.java:227)
    at com.itextpdf.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:1348)
    at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:244)
4

0 回答 0