java - PDF签名 itext pkcs7 多重签名

标签 java pdf itext digital-signature

我想对 pdf 文档进行多重签名,就像在工作流程中一样。 我正在使用以下代码来签署我编写的 pdf,效果很好。

获取哈希值

public String getHash() {
    LOGGER.debug("PDFSigner.getHash : method invoked");
    String pdfHashValue = null;
    try {
        int contentEstimated = PDFSigner.CONTENT_ESTIMATED;//8192
        HashMap<PdfName, Integer> exc = new HashMap<>();
        exc.put(PdfName.CONTENTS, contentEstimated * 2 + 2);
        PdfSignature pdfSignature = new PdfSignature(PdfName.ADOBE_PPKLITE,
                PdfName.ADBE_PKCS7_DETACHED);
        pdfSignature.setReason(appearance.getReason());
        pdfSignature.setLocation(appearance.getLocation());
        pdfSignature.setContact(appearance.getContact());
        pdfSignature.setDate(new PdfDate(appearance.getSignDate()));
        appearance.setCryptoDictionary(pdfSignature);
        appearance.preClose(exc);
        InputStream data = appearance.getRangeStream();
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        byte buf[] = new byte[contentEstimated];
        int n = 0;
        while ((n = data.read(buf, 0, contentEstimated)) > 0) {
            messageDigest.update(buf, 0, n);
        }
        byte hash[] = messageDigest.digest();
        byte[] reqBytesdata = Hex.encode(hash);
        pdfHashValue = new String(reqBytesdata, "UTF8"); 
    } catch (Exception exp) {
        LOGGER.error("PDFSigner error occured getHash", exp);
    }
    return pdfHashValue;
}

签署文件

//dSignature is the received encoded signature pkcs7 (SHA256).
//starts with MIIOWQYJKoZIhvcNAQcCo.....
    public boolean doSign(String dSignature) throws IOException, DocumentException {

        boolean pdfGenerationStatus = false;
        try {
            byte[] PKCS7Response = Base64.decode(dSignature
                    .getBytes("UTF8"));
            byte[] paddedSig = new byte[PDFSigner.CONTENT_ESTIMATED];
            System.arraycopy(PKCS7Response, 0, paddedSig, 0,
                    PKCS7Response.length);
            PdfDictionary pdfDictionary = new PdfDictionary();
            pdfDictionary.put(PdfName.CONTENTS,
                    new PdfString(paddedSig).setHexWriting(true));  
            appearance.close(pdfDictionary);
            pdfGenerationStatus = true;

        } catch (Exception exp) {
            LOGGER.error("doSign ", exp);
        }
        return pdfGenerationStatus; 

    }

上面的代码工作正常。 我的新要求是添加多重签名。有什么方法可以重用此代码片段吗? 我已经经历过this , thisthis但运气不佳。

除此之外,我尝试的是创建空白的多个空白签名并尝试附加签名。但它导致创建损坏的文件。我还尝试使用此 link 中提到的方法创建文件。 MakeSignature.signExternalContainer 还浏览了一篇很棒的文档 PDF 文档的数字签名

用例就像

  1. 创建 PDF
  2. 生成文档哈希
  3. 发送到外部服务器
  4. 外部服务器将返回 pkcs7 base64 编码的字符串
  5. 将签名附加到 pdf

更新

代码更改是为了“追加模式”,以下代码更改使我的代码支持多重签名,感谢@Paulo Soares、@mlk

private void initAppearanceAppend(String customerName) throws IOException, DocumentException {
    System.out.println("PDFSigner.initAppearanceAppend");
    PdfReader readerpdf = new PdfReader(this.getInputPdfFilePath());
    int lastPageNumber = readerpdf.getNumberOfPages();
    this.pdfSignatureMetaData.setPageNumber(lastPageNumber);
    this.pdfSignatureMetaData.setSignerName(customerName);
    //this.pdfSignatureMetaData.setPageNumber(PDFSigner.SIGNATURE_PAGE_NUMBER);
    OutputStream fout = new FileOutputStream(this.outputPdfFilePath);
    //PdfStamper stamperpdf = PdfStamper.createSignature(readerpdf, fout, '\0'); OLD CODE WITHOUT APPEND MODE
    PdfStamper stamperpdf = PdfStamper.createSignature(readerpdf, fout, '\0', new File("E://temp"), true);

    this.appearance = stamperpdf.getSignatureAppearance();
    LOGGER.debug("PDFSigner.initAppearanceAppend : default configurations are made");
}

最佳答案

(您使用的是 iText 2.1.7,不是吗?它很旧,很多问题在 5 中得到解决,更多问题在 7 中得到解决。)

添加更多签名与添加第一个签名相同,只是使用附加模式。除非第一个签名是经过认证且具有适当权限的签名,否则只有最后一个签名会显示为有效,但它们都是有效的,只需提取修订版本即可检查。

关于java - PDF签名 itext pkcs7 多重签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48706696/

相关文章:

java - 保护数据库免受 Java 客户端的攻击

java - CriteriaBuilder 不粘贴函数参数

pdf - 如何确定 pdf 文档中单词的字体系列和字体大小?

java - 轻松重构抽象类的静态方法调用

php - HTML 到 pdf 没有给出所有样式的正确 pdf

java - 如何将pdf上传到MySQL数据库并通过元数据搜索?

c# - 获取单元格占用的行数 Itextsharp

java - 使用 Java 和 Itext 编辑 PDF 文本

java - 更改 iText 中的文本大小

java - 将高尔夫分数放入数组中