我正在将PDF转换为PDF / A。 我已经通过付费的PDFTools库进行了此转换,转换的结果已放置在此页面上,该页面负责验证其是否符合PDA / A标准https://www.pdf-online.com/osa/validate.aspx 验证表明它符合标准。 转换后,将使用Itext 5.5.5库对PDF进行签名,但是,如果我再次使用验证器,则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)