我正在使用iText
签署带有数字证书的pdf。现在我可以签名并添加LTV,但CertificateLevel可以是:
signatureAppearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);
我只是想设置PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED
。最终结果应如下所示:
sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
MakeSignature.signDetached(signatureAppearance, privateKey, "SHA-512", chain, null, ocspClient, tsaClient, 0, MakeSignature.CryptoStandard.CADES);
如果我使用上面的代码进行签名,那么使用AdobeLtvEnabling.java添加LTV将在使用ACROBAT检查时提示签名无效,因为该文件在添加LTV时正在修改不可修改的PDF文件。因此,我能做些什么才能达到最终效果。
要获得像快照中的结果,即“不允许更改”和“Signature已启用LTV”而没有任何后续签名或文档时间戳,您必须
不幸的是,Adobe Acrobat Reader似乎尚未正确支持后一种变体。
有关详细信息,请参阅以下部分
首先,这并不总是可行的。如果您希望在原始签名修订中包含LTV材料,则它必须是签名数据的一部分,因此您必须在签名之前收集它。但是,在许多使用远程签名服务的设置中,您不知道在实际请求签名之前将使用哪个签名证书。
但是,如果有可能,即如果您事先知道签名证书,则可以使用AdobeLtvEnabling
中的this stack overflow answer类来包含以下信息:
PdfStamper stamper = PdfStamper.createSignature(...);
AdobeLtvEnabling adobeLtvEnabling = new AdobeLtvEnabling(stamper);
OcspClient ocsp = new OcspClientBouncyCastle();
CrlClient crl = new CrlClientOnline();
adobeLtvEnabling.addLtvForChain(YOUR_SIGNER_CERTIFICATE, ocsp, crl, PdfName.A);
adobeLtvEnabling.outputDss();
[...preparing your signature...]
MakeSignature.signDetached(...);
(CreateSignatureComodo测试testCreateLtvNoChangesAllowedCertification
)
您可能必须将AdobeLtvEnabling
方法addLtvForChain
和outputDss
公之于众,因为AdobeLtvEnabling
最初并不打算像这样使用。
结果:
或者,您可以以允许稍后添加LTV材料的方式签署您的PDF,尽管“不允许更改”认证。
首先,如果要在应用其所需的签名后将LTV材料添加到PDF,则必须使用首先为PAdES签名指定的机制。虽然这种机制同时包含在ISO 32000-2中,但它在普通的ISO 32000-1环境中不可用。但是,截图是Adobe Acrobat的截图,这应该不是您的问题。
这种机制是文档安全存储。 iText类LtvVerification
和来自AdobeLtvEnabling
的this stack overflow answer类都用PDF填充这些商店。
是否允许添加这些文档安全存储,尽管“不允许更改”认证? - 这取决于...
如果您的PDF是PDF-2.0:是的。 ISO 32000-2描述了某些认证允许或禁止的更改,如下所示:
对增量更新的PDF的更改,其中仅包括将DSS的12.8.4.3,“文档安全性存储(DSS)”和/或文档时间戳12.8.5,“文档时间戳(DTS)字典”添加到文档所需的数据不被视为对以下选项中定义的文档的更改。
(ISO 32000-2,表257 - DocMDP转换参数字典中的条目)
如果您的PDF是启用了PAdES扩展名的PDF-1.x:是的。 ETSI EN 319 142-1要求
DocMDP限制(参见ISO 32000-1 1,第12.8.2.2节)不适用于包含DSS字典和相关VRI,Certs,CRL和OCSP的PDF文档的增量更新。
...
在评估DocMDP限制时(参见ISO 32000-1 1,第12.8.2.2节),应忽略文档时间戳字典项的存在。
(ETSI EN 319 142-1 V1.1.1,第5.4节验证数据和存档验证数据属性)
如果你的PDF是普通的PDF-1.x,不过:不!
因此,如果要使用此选项并在签名后添加LTV信息,请确保您最初认证的PDF是PDF-2或至少启用了PAdES扩展。
虽然iText 5不支持PDF-2,但使用它创建PAdES样式签名会添加PAdES扩展。
因此,如果您认证PAdES风格,即使认证是“不允许更改”,您也应该能够LTV启用签名。
完成了一些延长无变化的测试后,只允许使用LTV信息进行认证PDF,PDF标记为PDF-1.7,带有适当的ETSI和Adobe扩展或PDF-2.0,似乎Adobe Acrobat既不支持ETSI EN 319 142 -1还是完全没有ISO 32000-2:在所有测试中,它都认为认证是破损的,参见CreateSignatureComodo测试testCreateNoChangesAllowedCertificationAndLtv
。
因此,目前为了获得LTV启用无变更允许认证的文档并让Adobe Acrobat认识到这一点,只有上面的第一个选项,即将所有LTV材料包括在原始签名修订中。
解决方法可能是创建允许表单填写的证书,然后添加LTV信息,然后使用另一个(批准)签名进行签名,该签名通过其字段锁定字典及其FieldMDP转换将文档更改为不允许更改,参见CreateSignatureComodo测试testCreateCertificationAndLtvAndNoChangesAllowed
。但是,由于知识渊博的人可以删除该签名的增量更新,但这远非完美。
解决方案的结果:
我正在使用itextsharp,我想以下内容对您的Java代码也很有用。
如果你用MakeSignature.SignDetached
和CrlClient
调用OcspClient
(而不是传递null
作为参数),你将在第一步之后得到一个支持LTV的签名。然后,您无需在第二步之后添加文档时间戳。
var stamper = PdfStamper.CreateSignature(reader, stream, '\0', null, true);
var appearance = stamper.SignatureAppearance;
appearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
...
var privateKey = ...
var chain = ...
var crlClient = new CrlClientOnline(chain);
var ocspClient = new OcspClientBouncyCastle();
var tsaClient = new TSAClientBouncyCastle("http://....");
MakeSignature.SignDetached(appearance, privateKey, chain,
new[] { crlClient },
ocspClient,
tsaClient,
0,
CryptoStandard.CMS);
stamper.Close();
希望这对你有用。