从pdf中检索pkcs7文件并进行共同签名 [英] retrieve the pkcs7 file from pdf and co-sign

查看:604
本文介绍了从pdf中检索pkcs7文件并进行共同签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个签名的PDF文件和.p7s文件.我需要从PDF检索.p7s并共同签署PDF(生成其他.p7s). 之后,我需要再次将p7s转换为PDF文件. 当我尝试从PDF获取p7s时出现此错误: ExceptionConverter:java.security.SignatureException:未初始化用于签名的对象 我的代码:

I have a PDF file signed and .p7s file. I need retrieve .p7s from PDF and co-sign the PDF (generating other .p7s). After I need put again the p7s into PDF file. I get this error when I try get p7s from PDF: ExceptionConverter: java.security.SignatureException: object not initialized for signing My code:

BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);

PdfReader pdfReader = new 
PdfReader(Files.readAllBytes(inputFile.toPath()));

AcroFields acroFields = pdfReader.getAcroFields();          
List<String> signatures = acroFields.getSignatureNames();

for (String name : signatures) {
   PdfPKCS7 pdfPkcs7 = acroFields.verifySignature(name, "BC");
   Files.write(Paths.get("~/TEST/itext/"+ name +".p7s"), 
   pdfPkcs7.getEncodedPKCS7());//ERROR HERE!
}

推荐答案

理论上

您要通过从PDF中提取嵌入式CMS签名容器,向其中添加签名,然后重新嵌入,来共同签名PDF (计数器符号?并行符号?).扩展容器.

In Theory

You want to co-sign the PDF (counter-sign? parallel-sign?) by extracting an embedded CMS signature container from a PDF, adding your signature to it, and re-embedding the extended container.

这是错误的方法,PDF签名被设计为仅在每个PDF签名字段中包含一个签名,而我们所讨论的CMS签名容器本质上就是该字段的值,因此每个嵌入式签名容器应恰好包含一个签名

This is the wrong approach, PDF signing is designed to contain a single signature only per PDF signature field and the CMS signature container we talk about essentially is the value of such a field, so each embedded signature container shall contain exactly one signature.

严格来说,PDF规范允许您使用任意的自定义签名方案,只有可互操作的签名"受到限制.因此,具有多个签名的签名容器可以被视为有效的PDF,而不能被视为可互操作签名",即您不应期望任何其他软件像您那样来解释签名.特别是Adobe Acrobat Reader将仅识别和显示这些签名之一.

(实际上也有一些大型签名解决方案提供商在PDF中嵌入了多签名CMS容器.例如,我目前必须处理由嵌入了任意CAdES-A签名容器(尤其是嵌入式CAdES-A签名容器)的某些提供商生成的签名.一些带有多个签名者的文件)转换为PDF,并将这种签名格式称为PDF/CAdES-A,现在,我必须向他们的客户解释,他们的签名可以是PDF签名,但不能互操作,即使该名称PDF/CAdES-A听起来像一些很棒的标准...)

PDF中的多个签名具有互操作性,必须像此草图中所示的那样顺序应用:

Multiple signatures in PDFs for interoperability must be applied sequentially like visualized in this sketch:

有关某些背景和更多信息的链接,请参阅. 此答案.

For some backgrounds and links to more information, cf. this answer.

您的代码似乎是iText 5.5.x代码,尤其不是iText 7.x代码.在这种情况下,您可以使用 PDF文档的数字签名 Bruno Lowagie 的白皮书.

Your code appears to be iText 5.5.x code, in particular not yet iText 7.x code. In that case you can use the code from the Digital Signatures for PDF Documents white book by Bruno Lowagie as is.

一个非常简单的例子:

public void sign(String src, String dest, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
        String provider, CryptoStandard subfilter, String reason, String location)
        throws GeneralSecurityException, IOException, DocumentException {
    // Creating the reader and the stamper
    PdfReader reader = new PdfReader(src);
    FileOutputStream os = new FileOutputStream(dest);
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
    // Creating the appearance
    PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
    appearance.setReason(reason);
    appearance.setLocation(location);
    appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
    // Creating the signature
    ExternalDigest digest = new BouncyCastleDigest();
    ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider);
    MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);
}

(代码示例2.1:使用iText签名的"Hello World")

由于您的用例涉及签署已经签署的文档,因此只需将PdfStamper.createSignature行更改为

As your use case involves signing an already signed document, you merely have to change the PdfStamper.createSignature line to

PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', true);

(请在末尾注意新的布尔参数).此更改将导致在追加模式中创建签名,从而使以前的修订版具有原始签名,而不会使该签名失效.

(notice the new boolean argument at the end). This change causes the signature to be created in append mode which leaves the former revision with the original signature as is to not invalidate that signature.

这篇关于从pdf中检索pkcs7文件并进行共同签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆