如何使用 Java 在 itext 中 PAdES BASELINE LT & LTA?

JK_*_*des 3 java itext digital-signature itext7 pades

我正在使用 itext7 处理 pdf 签名,目前需要支持所有 PAdES 签名级别:BB、BT、B-LT、B-LTA https://ec.europa.eu/digital-building-blocks/wikis/display/ ESIGKB/电子签名的 BT-LT 和 LTA 级别是什么

我的问题是如何使用 itext 创建 B-LT 签名?我用以下代码创建了 BB 和 BT:

signer.signDetached(
                new BouncyCastleDigest(),
                customExternalSignature,
                new Certificate[]{clientX509Certificate},
                null,
                null,
                tsaClient,
                0,
                PdfSigner.CryptoStandard.CADES);
Run Code Online (Sandbox Code Playgroud)

然后我想添加 B-LTA 级别,所以我使用了此代码https://github.com/mkl-public/testarea-itext7/blob/master/src/main/java/mkl/testarea/itext7/signature/AdobeLtvEnabling。 java 检查添加 BASELINE-LTA 级别,但将此逻辑应用到我的签名 adobe 后说它是 BASELINE-LT

在此输入图像描述

这产生了两个问题:

  1. AdobeLtvEnabling 中的此实现是否是添加 PAdES 级别 B-LT 的正确方法?
  2. 这是添加 B-LTA 级别的正确方法吗?
//This method extend B-T signature to B-LT
private byte[] addLt(final byte[] signed) throws IOException, GeneralSecurityException {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (InputStream resource = new ByteArrayInputStream(signed);
             PdfReader pdfReader = new PdfReader(resource);
             PdfWriter pdfWriter = new PdfWriter(out);
             PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().preserveEncryption().useAppendMode())) {
            AdobeLtvEnabling adobeLtvEnabling = new AdobeLtvEnabling(pdfDocument);
            IOcspClient ocsp = new OcspClientBouncyCastle(null);
            ICrlClient crl = new CrlClientOnline();
            adobeLtvEnabling.enable(ocsp, crl);
        }

        return addLtv(out.toByteArray());
    }

//This method extend B-LT signature to B-LTA
private byte[] addLtv(final byte[] pdf) throws IOException, GeneralSecurityException {
        final ByteArrayOutputStream signedFile = new ByteArrayOutputStream();
        final PdfReader sourceDoc = new PdfReader(new ByteArrayInputStream(pdf));
        final PdfSigner signer = new PdfSigner(sourceDoc, signedFile, STAMPING_PROPERTIES);

        signer.timestamp(tsaClient, null);

        return signedFile.toByteArray();
    }
Run Code Online (Sandbox Code Playgroud)

mva*_*val 5

看起来差不多是对的。PAdES-B-LT 和 PAdES-B-LTA 之间的唯一实质性区别是签名验证数据也需要加上时间戳。因此,要从 PAdES-B-LT 转到 PAdES-B-LTA,只需添加文档时间戳即可。

对于 iText,或多或少是这样工作的:

try(InputStream is = ...; // this should contain the PAdES-B-LT output
    PdfReader reader = new PdfReader(is);
    OutputStream os = new FileOutputStream(OUTPUT_DOCUMENT)) {

    PdfSigner pdfSigner = new PdfSigner(reader, os, new StampingProperties().useAppendMode());
    // .timestamp(...) is for producing document timestamps
    pdfSigner.timestamp(tsaClient, timeStampFieldName);
}
Run Code Online (Sandbox Code Playgroud)

另请参阅此处了解一些上下文:https://dzone.com/articles/7-tips-for-creating-pdf-signatures(忽略嗡嗡声标题...)。

编辑:如果您正在寻找一个工具来测试 PAdES 签名是否符合规范中的格式要求,您可能需要请求访问 ETSI 一致性检查器:https: //signatures-conformance-checker.etsi.org /pub/index.php