如何在将 .p7s 注入 Pdf 时添加 Ltv 和 CRL(离线)?

How to add Ltv & CRL (offline) while injecting .p7s to a Pdf?

我使用以下代码将 p7s 注入 Pdf:

        PdfWriter pdfWriter = new PdfWriter("results/final1.pdf");
        PdfDocument document = new PdfDocument(new PdfReader("results/prepared1.pdf"), pdfWriter, new StampingProperties().UseAppendMode());
        Stream output = new FileStream("results/signed1.pdf", FileMode.Create);

        ExternalInjectingSignatureContainer container2 = new ExternalInjectingSignatureContainer(_p7s);

        List<byte[]> crlCollection = new List<byte[]>();
        crlCollection.Add(File.ReadAllBytes(@"ks/mycrls.crl"));

        PdfSigner.SignDeferred(document, "Signature1", output, container2);

找到这个

我找到了this

我试过如下:

        ICrlClient clrClient = new CrlClientOffline(File.ReadAllBytes(@"ks/mycrls.crl"));
        addLTV("results/signed1.pdf", "results/final1.pdf", null, clrClient, null);

我没有看到 Ltv 已启用?

但结果是:未执行吊销检查。

addLtv

public static void addLTV(String src, String dest, IOcspClient ocsp, ICrlClient crl, ITSAClient itsaClient)
    {
        PdfReader reader = new PdfReader(src);
        PdfWriter writer = new PdfWriter(dest);
        PdfDocument pdfDoc = new PdfDocument(reader, writer, new StampingProperties().UseAppendMode());
        LtvVerification v = new LtvVerification(pdfDoc);
        SignatureUtil signatureUtil = new SignatureUtil(pdfDoc);
        IList<string> names = signatureUtil.GetSignatureNames();
        String sigName = names[names.Count - 1];
        PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(sigName);
        if (pkcs7.IsTsp())
        {
            v.AddVerification(sigName, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN,
                LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
        }
        else
        {
            foreach (var name in names)
            {
                v.AddVerification(name, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN,
                    LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.YES);
                v.Merge();
            }
        }

        pdfDoc.Close();
    }

ExternalInjectingSignatureContainer

internal class ExternalInjectingSignatureContainer :IExternalSignatureContainer
{
    public ExternalInjectingSignatureContainer(byte[] signature)
    {
        Signature = signature;
    }

    public void ModifySigningDictionary(PdfDictionary signDic)
    {

    }

    public byte[] Sign(Stream data)
    {
        return Signature;
    }

    public byte[] Signature;
}

我想通过添加 CRL 信息(离线)来改进它,我已经创建了一个 .crl 文件,但我不知道如何在注入 .p7s 时添加 crl?

时间戳

我知道这与这个问题无关,但之后我会在签名中添加一个时间戳,我在哪里可以找到免费的时间戳(用于开发目的)?

任何帮助将不胜感激..

非常感谢

如何在将 .p7s 注入 Pdf 时添加 Ltv 和 CRL(离线)?

这取决于您创建的 PDF 签名的配置文件和验证器的能力。

ISO 32000 中使用的 PKCS#7 签名

第 1 部分和第 2 部分中的 PDF 标准 ISO 32000 第 12.8.3.3 节(“ISO 32000 中使用的 PKCS#7 签名”/“CMS (PKCS #7) 签名”)定义了一个配置文件用于 PDF 中的 CMS 签名。

此配置文件需要吊销信息作为签名属性包含在 CMS 容器中

根据您之前的问题判断,您在外部创建了 CMS 签名容器本身。因此,要根据此配置文件嵌入 CRL,您必须更新生成 CMS 容器的外部代码,或者(如果您未实现的某些服务创建了这些签名)要求签名创建服务提供商更新其生成 CMS 容器的代码以包含ISO 32000 第 12.8.3.3.2 节(“撤销信息”/“基于 CMS 的签名的撤销”)中详述的签名属性中的 CRL。

PDF 中使用的 CAdES 签名

ETSI 最初在 TS 102 778 中,在 EN 319 142 中更新,为 PDF 中的 CAdES 签名定义了配置文件(PAdES 配置文件)。 CAdES 是 CMS 的一个特殊配置文件。这些配置文件的摘要已复制到更新的 PDF 规范 ISO 32000-2,第 12.8.3.4 节(“PDF 中使用的 CAdES 签名”)。

这些配置文件需要将吊销信息嵌入增量更新之后文档安全存储 PDF 对象结构中的签名修订.

因此,要根据这些配置文件嵌入 CRL,您需要签名的 PDF 并在之后添加 CRL。这基本上就是您的 addLTV 示例所做的。

为什么未执行吊销检查

在评论中您提到您使用 PAdES 并使用 addLTV 示例添加 CRL,但 Adob​​e Reader 告诉您“未执行撤销检查”。

如果您阅读了该消息下面的文字,原因就很清楚了:

The selected certificate does not chain up to a certificate designated as trusted anchor (see the Trust Tab for details). The result is that revocation checks were not performed on this certificate.

如果您的验证器无法将您的签名者证书(在证书链中)追溯到它明确信任的证书,则验证将停止,有效期为 未知。仅当验证者(直接或间接)信任签名者证书的颁发者时,撤销检查才有意义;只有在颁发者信任的情况下,验证器才需要验证颁发者是否撤销了证书。