OscpVerifier 根据当前日期而不是 signDate 验证 OCSP 签名者证书 - 错误或功能?

OscpVerifier validating OCSP signers certificate against current date instead of signDate - bug or feature?

我正在使用 iTextSharp 5.5.13 来签署和验证 PDF 文件。几天前,我在 OcspVerifier.Verify 中遇到了 异常,其中说明 "certificate expired on 20181225...GMT+00:00"

所有 PDF 文件都使用嵌入的 OCSP 响应和 CLR 进行签名。验证是使用签名日期完成的,它过去工作正常直到 ocsp 签名者证书过期

尽管所有证书在签名时都是有效的,OcspVerifier.Verify 开始抛出异常 "cert expired..."。

if (pkcs7.Ocsp != null)
     ocsps.Add(pkcs7.Ocsp);
PdfOcspVerifier ocspVerifier = new PdfOcspVerifier(null, ocsps);
ocspVerifier.OnlineCheckingAllowed = false;
List<VerificationOK> verification = ocspVerifier.Verify(signCert, issuerCert, signDate.ToUniversalTime());

EXCEPTION: "certificate expired on 20181225...GMT+00:00"

我觉得这像是 bug?有什么原因导致 OCSP 签名者证书未根据签名日期进行验证吗?

Class OscpVerifier - 原始,包含根据当前日期验证证书的行:

 virtual public void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert)
{
....
    //check if lifetime of certificate is ok
    responderCert.CheckValidity();
}

OscpVerifier.cs的修改版本:

// old definition with old functionality
virtual public void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert)
{
            IsValidResponse(ocspResp, issuerCert, DateTime.UtcNow);
}

// with signDate parameter:
virtual public void IsValidResponse(BasicOcspResp ocspResp, X509Certificate issuerCert, DateTime signDate)
{
...

    //check if lifetime of certificate is ok
    responderCert.CheckValidity(signDate);
    //responderCert.CheckValidity();
}

相应的方法调用更改为:

virtual public bool Verify(BasicOcspResp ocspResp, X509Certificate signCert, X509Certificate issuerCert, DateTime signDate)
{
...
...     {
            // check if the OCSP response was genuine
            IsValidResponse(ocspResp, issuerCert);
            return true;
        }
...
}

至:

virtual public bool Verify(BasicOcspResp ocspResp, X509Certificate signCert, X509Certificate issuerCert, DateTime signDate)
{
...
...     {
            // check if the OCSP response was genuine
            IsValidResponse(ocspResp, issuerCert, signDate);
            return true;
        }
...
}

我将 OscpVerifier class 的这个变体直接包含在项目中,它现在按预期验证了旧签名。

但是,我不确定我是否遇到了错误或者这些签名应该被视为无效的原因?

OCSP 签名者证书必须在当前时间进行验证,除非 OCSP 响应已使用时间戳进行保护,这样 itext 才能正常工作。


总而言之,OCSP 响应包含(参见 RFC6960):

  • 目标证书和有效期间隔

  • 生成响应的时间

  • CA 可信响应者的数字签名及其证书

接受 OCSP 响应的标准在 RFC 中建立,但它没有阐明您的问题,因为它没有确定如何随着时间的推移验证响应。

3.2. Signed Response Acceptance Requirements

Prior to accepting a signed response for a particular certificate as valid, OCSP clients SHALL confirm that:

  1. The certificate identified in a received response corresponds to the certificate that was identified in the corresponding request;
  1. The signature on the response is valid;
  1. The identity of the signer matches the intended recipient of the request;
  1. The signer is currently authorized to provide a response for the certificate in question;
  1. The time at which the status being indicated is known to be correct (thisUpdate) is sufficiently recent;
  1. When available, the time at or before which newer information will be available about the status of the certificate (nextUpdate) is greater than the current time.

但是,它确实表明数字签名必须有效(2)。一般来说,一个签名被认为是有效的,它必须符合:

  • 加密完整性

  • 证书的有效期(过期和吊销)

带有过期证书的 OCSP 响应不符合第二个标准,因此应该被拒绝。为了延长签名的有效期,必须在内容上加上时间戳。 PAdES 标准规定了如何

还有一份 ETSI 指南,其中详细介绍了如何执行 PAdES 和 CAdES 签名验证,但不幸的是我现在还没有找到 link