获取OcspClient和CrlClient以在LTV时间戳中使用

时间:2018-10-09 13:58:03

标签: pdf itext

我正在使用this来签名PDF文档,因为相关问题反映了我的情况。但是,由于无法实例化要在addLtv函数中使用的有效OscpClient和CrlClient对象,因此无法生成LTV(我使用this作为指导)。我正在使用iTextSharp 5.5.10。

是否有一些文档可以指向正确的方向?

这是我目前的状态:

try {
    // Getting the certificate 
    X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
    X509Certificate2 x509 = selectCert(store.Certificates, "<<some descriptor>>");

    // Initialise the various objects
    PdfReader pdfReader = new PdfReader("<<path to source file>>");
    FileStream signedPdf = new FileStream("<<path to dest file>>", FileMode.Create);

    PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0', null, true);
    pdfStamper.MoreInfo = pdfReader.Info;

    PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;
    X509Certificate2Signature externalSignature = new X509Certificate2Signature(x509, "SHA-256");

    Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser();
    Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] {
        cp.ReadCertificate(x509.RawData)
    };

    // Initialise the IOcspClient implementor
    // https://itextsupport.com/apidocs/itext5/latest/com/itextpdf/text/pdf/security/OcspClientBouncyCastle.html
    OcspClientBouncyCastle ocsp = new OcspClientBouncyCastle(
        // The first point that I get stuck on the documentation
        new OCSPVerifier()
    );

    // Initialise the ICrlClient implementor
    // https://itextsupport.com/apidocs/itext5/latest/com/itextpdf/text/pdf/security/CrlClientOnline.html
    CrlClientOnline crl = new CrlClientOnline(
        // https://stackoverflow.com/a/40894818
        GetCrlDistributionPointURI(x509)
    );

    List<String> names = pdfStamper.AcroFields.GetSignatureNames();
    String sigName = names[names.Capacity - 1];
    PdfPKCS7 pkcs7 = pdfStamper.AcroFields.VerifySignature(sigName);

    // The long term validation
    if (pkcs7.IsTsp) {
        pdfStamper.LtvVerification.AddVerification(
            sigName, ocsp, crl,
            LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
            LtvVerification.Level.OCSP_CRL,
            LtvVerification.CertificateInclusion.NO
        );
    }
    else {
        foreach (String name in names) {
            pdfStamper.LtvVerification.AddVerification(
                name, ocsp, crl,
                LtvVerification.CertificateOption.WHOLE_CHAIN,
                LtvVerification.Level.OCSP_CRL,
                LtvVerification.CertificateInclusion.NO
            );
        }
    }

    // Sign the doc and 
    MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
    pdfStamper.Close();
    return "Done";
}

catch (Exception ex) {
    return ex.Message;
}

1 个答案:

答案 0 :(得分:1)

OCSP客户端

// Initialise the IOcspClient implementor
// https://itextsupport.com/apidocs/itext5/latest/com/itextpdf/text/pdf/security/OcspClientBouncyCastle.html
OcspClientBouncyCastle ocsp = new OcspClientBouncyCastle(
    // The first point that I get stuck on the documentation
    new OCSPVerifier()
);

首先,如果要验证OCSP响应,则仅需要一个OcspVerifier实例。由于您的任务是生成带有LTV信息的签名,因此,如果您确定您的程序不必处理受损的CA PKI基础结构,则可以跳过此验证。即你可以做

OcspClientBouncyCastle ocsp = new OcspClientBouncyCastle(null);

(甚至

OcspClientBouncyCastle ocsp = new OcspClientBouncyCastle();

如果过时的标签不会打扰您)。

否则,如果您确实要验证OCSP响应,则OCSPVerifier构造函数具有两个参数:

/**
 * Creates an OCSPVerifier instance.
 * @param verifier  the next verifier in the chain
 * @param ocsps a list of OCSP responses
 */
public OcspVerifier(CertificateVerifier verifier, List<BasicOcspResp> ocsps)

由于您既不知道将OCSP响应验证基于某些CertificateVerifier,也没有准备好的OCSP响应列表,因此您是否尝试过简单使用

OcspClientBouncyCastle ocsp = new OcspClientBouncyCastle(
    new OCSPVerifier(null, null)
);

CRL客户端

// Initialise the ICrlClient implementor
// https://itextsupport.com/apidocs/itext5/latest/com/itextpdf/text/pdf/security/CrlClientOnline.html
CrlClientOnline crl = new CrlClientOnline(
    // https://stackoverflow.com/a/40894818
    GetCrlDistributionPointURI(x509)
);

如果您的代码失败(我无法检查,因为您没有解释该GetCrlDistributionPointURI方法):您是否尝试过使用默认构造函数:

CrlClientOnline crl = new CrlClientOnline();

这取决于您的PKI ..​​.

启用LTV

不清楚您要向PDF添加哪些LTV信息。正如您没有提到 PAdES 一样,我假设您想添加Adobe专有的“启用LTV”检查的信息。

在这种情况下,您可能只想尝试从this answer到问题"I want to sign a pdf document with ITextSharp and return ltv pdf enabled file"AdobeLtvEnabling类。