当iText使用PDfStamperin正常模式操作文档时,它可以(并且经常)重新排列现有的PDF对象.这显然打破了任何现有集成签名的哈希值.此外,必须签名的字节范围也会发生变化.这很可能是你的问题.
当iText使用PDfStamperin追加模式操作文档时,它会按原样保留PDF并仅附加其添加和更改.虽然这通常是保持集成签名不被破坏的方法,但是您不能以这种方式更改签名的内容,因为有一些关于嵌入签名的规则比一般的PDF更严格.因此,切换到追加模式不会解决您的问题.
因此,iText有一个显式的方法来进行签名插入,而不会改变PDF:
MakeSignature.signDeferred(PdfReader reader,
String fieldName,
OutputStream outs,
ExternalSignatureContainer externalSignatureContainer)
throws DocumentException, IOException, GeneralSecurityException
它的名称是由于这个方法最初是针对延迟签名的用例,即首先准备PDF进行签名(即添加所有字典和散列字节范围所需的其他必要结构,包括留下一个空白签名容器最终将被注入),计算哈希值,并将其发送到其他服务,同时在本地存储准备好的PDF.一旦其他服务返回签名,就会找到准备好的PDF,并使用此方法将检索到的签名插入其中.
与您的用例的唯一区别在于差距中已经存在签名.但是,当使用signDeferred时,该签名将被您更新的签名覆盖.
说完这一切后,如果您希望在向无符号属性添加ocsp响应后,Adobe Reader可能会使用这些信息进行验证.在根据ISO-32000-1,第12.8.3.3节的ISOCS 32中使用的PKCS#7签名的集成PDF签名的上下文中,
the PKCS#7 object should contain […] Revocation information as an signed attribute (PDF 1.6): This attribute may include all the revocation information that is necessary to carry out revocation checks for the signer’s certificate and its issuer certificates. Since revocation information is a signed attribute, it must be obtained before the computation of the digital signature. This means that the software used by the signer must be able to construct the certification path and the associated revocation information. If one of the elements cannot be obtained (e.g. no connection is possible), a signature with this attribute will not be possible.