如何为时间戳签名启用LTV并设置不允许的pdf更改?

问题描述 投票:1回答:2

我正在使用iText签署带有数字证书的pdf。现在我可以签名并添加LTV,但CertificateLevel可以是:

signatureAppearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS);

我只是想设置PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED。最终结果应如下所示:

enter image description here

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文件。因此,我能做些什么才能达到最终效果。

java itext certificate digital-signature
2个回答
2
投票

要获得像快照中的结果,即“不允许更改”和“Signature已启用LTV”而没有任何后续签名或文档时间戳,您必须

  • 要么已将Adobe验证器所需的所有LTV材料都包含在原始签名修订版中
  • 或使用签名模式,允许您附加LTV材料,尽管不允许更改。

不幸的是,Adobe Acrobat Reader似乎尚未正确支持后一种变体。

有关详细信息,请参阅以下部分

Include all LTV material into the original signed revision

首先,这并不总是可行的。如果您希望在原始签名修订中包含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方法addLtvForChainoutputDss公之于众,因为AdobeLtvEnabling最初并不打算像这样使用。

结果:

screen shot

Use a signing mode which allows appending LTV material but nothing else

或者,您可以以允许稍后添加LTV材料的方式签署您的PDF,尽管“不允许更改”认证。

首先,如果要在应用其所需的签名后将LTV材料添加到PDF,则必须使用首先为PAdES签名指定的机制。虽然这种机制同时包含在ISO 32000-2中,但它在普通的ISO 32000-1环境中不可用。但是,截图是Adobe Acrobat的截图,这应该不是您的问题。

这种机制是文档安全存储。 iText类LtvVerification和来自AdobeLtvEnablingthis 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启用签名。

Support by Adobe Acrobat Reader DC 2019.008.20080

完成了一些延长无变化的测试后,只允许使用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。但是,由于知识渊博的人可以删除该签名的增量更新,但这远非完美。

解决方案的结果:

screen shot


0
投票

我正在使用itextsharp,我想以下内容对您的Java代码也很有用。

如果你用MakeSignature.SignDetachedCrlClient调用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();

希望这对你有用。

© www.soinside.com 2019 - 2024. All rights reserved.