使用 iTextSharp 将多个数字签名插入 PDF
Inserting Multiple digital signatures into PDF using iTextSharp
我正在使用 iTextSharp 和 pkcs11RsaSignature 在 PDF 文档的每一页上插入数字签名。以下是我的代码:
PdfReader pdfSource = new PdfReader(...);
NumberOfPages = pdfSource.NumberOfPages;
pdfSource.Close();
CurrentPage = 1;
while (CurrentPage <= NumberOfPages)
{
Temp3PDF = Temp1PDF;
Temp1PDF = Temp2PDF;
Temp2PDF = Temp3PDF;
PdfReader pdfSrc = new PdfReader(Temp1PDF);
FileStream pdfDes = new FileStream(Temp2PDF, FileMode.Create);
PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfSrc, pdfDes, '[=10=]', Path.GetTempFileName(), true);
PdfSignatureAppearance pdfSignAppearance = pdfStamper.SignatureAppearance;
pdfSignAppearance.Acro6Layers = false;
pdfSignAppearance.SetVisibleSignature(new iTextSharp.text.Rectangle(100, 100, 250, 150), CurrentPage, null);
MakeSignature.SignDetached(pdfSignAppearance, pkcs11RsaSignature, certPath, null, null, null, 0, CryptoStandard.CADES);
pdfStamper.Close();
pdfDes.Close();
pdfSrc.Close();
CurrentPage++;
}
可以看出,这不是一种非常优雅的编程方式,因为文件的读写次数与页数一样多。有没有其他方法可以在PDF文档的每一页上插入数字签名。
这里实际要做的是 - 如果 PDF 文档被拆分成页面(将来),因为内容没有改变,所以技术上数字签名应该对它签名的页面有效.但我意识到签名会失效。 (换句话说这个问题 - 有没有什么方法可以只对一页 pdf 而不是整个文档进行数字签名?)
致 Bruno Lowagie(您是专家):除了 PDF 规范中未提供之外,可以通过对仅在选定组件上计算的哈希值进行签名来对 PDF 文件进行部分签名。您认为有可能升级 PDF 规范以满足此类要求吗?感谢您的帮助。
What is actually wanted to do here is that - in case the PDF document is split into pages (in future), since the contents haven't changed, so technically digital signature should be valid for the pages it is signed.
这种思路是基于一种误解。是的,您在一个特定页面上看到了签名的可视化,但签名以加密方式签署了整个 PDF,唯一的例外是嵌入式 CMS 签名容器本身。
但是你自己发现了这件事。因此,让我们考虑一下您改写的问题:
But I realize the signature will get invalidated. (Rephrasing the question - Is there any way of digitally signing only one page of pdf and not entire document?)
过去有两种可能允许签署单页的方式:
- 使用 对象摘要 关注有问题的页面;
- 使用 字节范围摘要 仅包含涵盖与相关页面相关对象的字节范围。
但如今,这些技术不再可用,因为
- object digests 很久以前就被弃用了,ISO PDF 规范甚至不再提及它们;
- 即使 ISO 32000-1 仍然允许 字节范围摘要 来涵盖此类 PDF 片段集合,PDF 处理器(特别是 Adobe Reader)需要字节范围覆盖整个 PDF 文件,唯一的例外是嵌入的签名容器;较新的规范(例如 ETSI PAdES 规范和 ISO 32000-2 草案)也有此要求。
因此,不,没有办法只对一页 pdf 而不是整个文档进行数字签名,至少不是以可互操作的方式。
在多页 PDF 中实现类似于分页签名的选项是
- 将 PDF 拆分为多个 PDF,每个 PDF 仅包含一个页面;
- 签署这些单页 PDF;和
- 将所有这些单页 PDF 放入一个 PDF 便携式集合(又名投资组合),并安排它以正确的顺序一个接一个地显示包含的各个 PDF。
我正在使用 iTextSharp 和 pkcs11RsaSignature 在 PDF 文档的每一页上插入数字签名。以下是我的代码:
PdfReader pdfSource = new PdfReader(...);
NumberOfPages = pdfSource.NumberOfPages;
pdfSource.Close();
CurrentPage = 1;
while (CurrentPage <= NumberOfPages)
{
Temp3PDF = Temp1PDF;
Temp1PDF = Temp2PDF;
Temp2PDF = Temp3PDF;
PdfReader pdfSrc = new PdfReader(Temp1PDF);
FileStream pdfDes = new FileStream(Temp2PDF, FileMode.Create);
PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfSrc, pdfDes, '[=10=]', Path.GetTempFileName(), true);
PdfSignatureAppearance pdfSignAppearance = pdfStamper.SignatureAppearance;
pdfSignAppearance.Acro6Layers = false;
pdfSignAppearance.SetVisibleSignature(new iTextSharp.text.Rectangle(100, 100, 250, 150), CurrentPage, null);
MakeSignature.SignDetached(pdfSignAppearance, pkcs11RsaSignature, certPath, null, null, null, 0, CryptoStandard.CADES);
pdfStamper.Close();
pdfDes.Close();
pdfSrc.Close();
CurrentPage++;
}
可以看出,这不是一种非常优雅的编程方式,因为文件的读写次数与页数一样多。有没有其他方法可以在PDF文档的每一页上插入数字签名。
这里实际要做的是 - 如果 PDF 文档被拆分成页面(将来),因为内容没有改变,所以技术上数字签名应该对它签名的页面有效.但我意识到签名会失效。 (换句话说这个问题 - 有没有什么方法可以只对一页 pdf 而不是整个文档进行数字签名?)
致 Bruno Lowagie(您是专家):除了 PDF 规范中未提供之外,可以通过对仅在选定组件上计算的哈希值进行签名来对 PDF 文件进行部分签名。您认为有可能升级 PDF 规范以满足此类要求吗?感谢您的帮助。
What is actually wanted to do here is that - in case the PDF document is split into pages (in future), since the contents haven't changed, so technically digital signature should be valid for the pages it is signed.
这种思路是基于一种误解。是的,您在一个特定页面上看到了签名的可视化,但签名以加密方式签署了整个 PDF,唯一的例外是嵌入式 CMS 签名容器本身。
但是你自己发现了这件事。因此,让我们考虑一下您改写的问题:
But I realize the signature will get invalidated. (Rephrasing the question - Is there any way of digitally signing only one page of pdf and not entire document?)
过去有两种可能允许签署单页的方式:
- 使用 对象摘要 关注有问题的页面;
- 使用 字节范围摘要 仅包含涵盖与相关页面相关对象的字节范围。
但如今,这些技术不再可用,因为
- object digests 很久以前就被弃用了,ISO PDF 规范甚至不再提及它们;
- 即使 ISO 32000-1 仍然允许 字节范围摘要 来涵盖此类 PDF 片段集合,PDF 处理器(特别是 Adobe Reader)需要字节范围覆盖整个 PDF 文件,唯一的例外是嵌入的签名容器;较新的规范(例如 ETSI PAdES 规范和 ISO 32000-2 草案)也有此要求。
因此,不,没有办法只对一页 pdf 而不是整个文档进行数字签名,至少不是以可互操作的方式。
在多页 PDF 中实现类似于分页签名的选项是
- 将 PDF 拆分为多个 PDF,每个 PDF 仅包含一个页面;
- 签署这些单页 PDF;和
- 将所有这些单页 PDF 放入一个 PDF 便携式集合(又名投资组合),并安排它以正确的顺序一个接一个地显示包含的各个 PDF。