PDFBOX - 签名 PDF 时,不调用 SignatureInterface 的签名

PDFBOX - when signing PDF, SignatureInterface's sign is not called

我正在尝试使用 PDFBOX 库对 PDF 进行签名(主要遵循 GitHub 中 example 包中的 CreateSignature 和其他 类)。

采用 SignatureInterface 方法后,我将方法提供给 addSignature,但 sign 方法 未被调用.

相关代码片段:

private void signPDF(PDDocument document) throws Exception {
    PDSignature signature = new PDSignature();
    signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
    signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
    signature.setName("iSure");
    signature.setLocation("IL");
    signature.setReason("Security");
    signature.setSignDate(Calendar.getInstance(TimeZone.getTimeZone("UTC")));

    // this is the only 'foreign' call here, it looks exactly as in example
    setMDPPermission(document, signature, 1);

    document.addSignature(signature, new Signer());
}

调用 signPDF 后,文档立即保存到 OutputStream

PS:在 MDP 权限中,我需要删除 "DigestMethod" 条目,但未通过 PDF/A 元数据验证 - 正确吗?

嗯,追踪COSWriter流程,我终于发现当保存不是增量时,写签名方法根本没有被调用。这部分在示例中有明确说明,但我认为它仅与那些特定场景或继续使用 PDDocument 相关,而我的情况是签名实际上是流程中的终止操作。底线-我的错:(

所以我把上面的方法改成如下:

// since forced to saveIncremental, need to finilized the input document and return a new one
private PDDocument signPDF(PDDocument document) throws Exception {
    PDSignature signature = new PDSignature();
    ... this part stays exactly as it was
    document.addSignature(signature, new Signer());

    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        document.saveIncremental(baos);
        return PDDocument.load(baos.toByteArray());
    }
}

另一种可能性是将目标 OutputStream 传递给 signPDF 方法并在此处执行实际的流终止:保存文档并随后关闭它。

另一个方法是在主流程中调用 saveIncrementalsignPDF 调用方)。

所有这些变化对我来说就像在方法之间滚动外国问题...如果有人有更好的方法来布置它 - 我会很高兴听到。