替换PDF中的签名内容

如何在iText中完成? 我有一张带有客户签名的PDF。 我需要为无符号属性添加ocsp响应。

我知道如何使用改变签名本身

org.bouncycastle.cms.CMSSignedData.replaceSigners(...).getEncoded() 

但我不知道如何使用new PdfString(newSignature).setHexWriting(true)替换PDF中的new PdfString(newSignature).setHexWriting(true) 。 如果我使用此代码:

 PdfDictionary other = new PdfDictionary(); other.put(PdfName.CONTENTS, new PdfString(newSignature).setHexWriting(true)); dicSignature.merge(other); 

其中dicSignature是包含签名的字典,然后签名(在Adobe Reader中打开文档时)被破坏。

当iText在正常模式下使用PdfStamper处理文档时,它可以(并且经常)重新排列现有的PDF对象。 这显然打破了任何现有集成签名的哈希值。 此外,必须签名的字节范围也会发生变化。 这很可能是你的问题。

当iText在附加模式下使用PdfStamper处理文档时,它会PdfStamper的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可能会使用这些信息进行validation。 在根据ISO-32000-1的集成PDF签名的上下文中, 在ISO 32000中使用的第12.8.3.3节PKCS#7签名

PKCS#7对象应包含作为签名属性的撤销信息(PDF 1.6):该属性可包括对签名者证书及其颁发者证书进行撤销检查所需的所有撤销信息。 由于吊销信息是带符号的属性, 因此必须在计算数字签名之前获取。 这意味着签名者使用的软件必须能够构建证书路径和相关的撤销信息。 如果无法获得其中一个元素(例如,无法连接),则无法使用具有此属性的签名。