我目前正在处理一个过时的项目,该项目签署PDF/A并试图升级其依赖关系。这里的相关内容是co.lowagie.itext,我将其从1.4升级到了5.5.13.1。由于删除了函数PdfSignatureAppearance.setCrypto()
,所以发生了很多变化。我在这个问题中实现了修复(我在最新版本中实现了所需的jar(,现在得到了以下代码:
PdfStamper stp;
try {
stp = PdfStamper.createSignature(reader, fout, ' ');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
ExternalDigest digest = new BouncyCastleDigest();
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
ExternalSignature signature = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256, provider.getName());
MakeSignature.signDetached(sap, digest, signature, certificateChain, null, null, null, 0, MakeSignature.CryptoStandard.CMS);
stp.close();
}
为了进行比较,这里是旧代码:
PdfStamper stp;
try {
stp = PdfStamper.createSignature(reader, fout, ' ');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(privateKey, certificateChain, null, PdfSignatureAppearance.WINCER_SIGNED);
stp.close();
}
这就是我的问题所在。在测试过程中,我注意到这个新版本将PDF/A转换为PDF1.4,而旧版本没有这样做。我没有PDF或PDF签名的经验。
PDF/A-1是PDF-1.4的配置文件。所以,如果你的源PDF是PDF/A-1,那么一开始也是PDF-1.4,iText并没有改变它。
此外,旧的iText 1.4和新的iText 5.5.13PdfStamper
都不支持PDF/A。很可能你的测试在检查iText 1.4签署的PDF文件时根本没有意识到这一点。
不过,在iText 5.5.13的情况下,你可能会很幸运,因为在该版本中,iText还提供了一个支持PDF/a的PdfAStamper
(不过,这个类在一个单独的jar中,iText pdfa.jar(
因此,请使用PdfAStamper
而不是PdfStamper
重试。如果这仍然没有帮助,请在使用新的和旧的iText版本签名之前和之后,为您的输入PDF共享一个PDF/A文件代表示例。还提到你用哪个程序来确定PDF是否是PDF/a。。。
有两个问题阻碍了代码创建有效的PDF/A
第一个问题是,我没有使用PdfAStamper
类,这是为PDF/a盖章并保持其PDF/a有效性所必需的。
第二个问题是,签名的PDF/A需要一个签名,其中时间戳由外部tsa服务器设置。
PdfStamper stp;
try {
stp = PdfAStamper.createSignature(reader, fout, ' ', PdfAConformanceLevel.PDF_A_1A); //<-- PdfAStamper with the PdfAConformanceLevel.
TSAClient tsaClient = new TSAClientBouncyCastle("https://freetsa.org/tsr"); //<-- creating the TSAClient
PdfSignatureAppearance sap = stp.getSignatureAppearance();
ExternalDigest digest = new BouncyCastleDigest();
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
ExternalSignature signature = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256, provider.getName());
MakeSignature.signDetached(sap, digest, signature, certificateChain, null, null, tsaClient, 0, MakeSignature.CryptoStandard.CMS); //<-- Notice "tsaClient"
stp.close();
}