我有一个外部pdf签名提供程序,这是一个基于web浏览器的服务。
- 我需要先将pdf哈希发送到它
- 它返回签名文档(证书(
- 我使用
MakeSignature.SignDeferred()
方法将其映射为PDF
这一切都很顺利,但有一些局限性。例如
- 我需要预先填充所有签名字段(如果我错了,请更正(
MakeSignature.SignDeferred
不调用ModifySigningDictionary()
(意味着我在获得实际签名信息(名称、位置等(后无法更新PdfDictionary(
请给我一些示例代码,因为iTextSharp在我看来非常复杂:(
SignDeferred
仅用于将签名注入到准备充分的签名字段中。即,它保留PDF中的所有现有信息(如常规内容和签名字段值属性,如位置和原因(,并且只注入包含实际签名的新CMS签名容器。
它通常用于多步骤签名用例,如下所示:
-
准备一个用于在PDF中签名的签名字段,特别是设置位置和原因等签名属性,为稍后嵌入的签名生成占位符,以及(可选(生成匹配的签名外观。
这通常是使用
MakeSignature.SignExternalContainer
完成的,使用ExternalBlankSignatureContainer
或自定义外部签名容器实现,还从其"Sign"方法返回一个伪值。 -
根据准备好的PDF计算要签名的哈希值。
这通常使用在
SignExternalContainer
调用之后或者已经在所述自定义外部签名容器实现的Sign
方法中的该调用期间从PdfSignatureAppearance
对象检索的范围流来完成。 -
生成对该哈希进行签名的CMS签名容器。
这是一个自定义步骤,详细信息取决于您使用的签名服务或API的类型。特别是,您可能需要准备CMS签名容器,并且仅从该服务或API检索其裸签名字节,或者该服务或API可能已经为您生成了完整的CMS容器。
-
将CMS签名容器注入您准备好的PDF中。
这是使用
MakeSignature.SignDeferred
完成的。这一步实际上只注入了签名容器,其他什么都不改变。
只有在
- 步骤3中的实际签名调用可能花费太多时间,而没有合理的超时,例如,因为必须等待某个第二认证因素,例如,对当前正在睡眠的某个人类用户的某个确认
- 或者,步骤4必须在与初始步骤不同的过程中实现,甚至可能在不同的计算机上实现
否则,您应该实现一个自定义外部签名或外部签名容器类来调用签名服务或API,并在单个MakeSignature.SignDetached
或MakeSignature.SignExternalContainer
调用中使用它。
SignDeferred
同样可以用于替换PDF中已签名签名字段中的签名容器(如果该签名是最外层的(,例如,因为在原始签名中使用了错误的签名证书,或者因为您想向现有签名容器添加一些未签名的属性,例如签名时间戳。