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:
- The certificate identified in a received response corresponds to the certificate that was identified in the corresponding request;
- The signature on the response is valid;
- The identity of the signer matches the intended recipient of the request;
- The signer is currently authorized to provide a response for the certificate in question;
- The time at which the status being indicated is known to be correct (thisUpdate) is sufficiently recent;
- 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
我正在使用 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:
- The certificate identified in a received response corresponds to the certificate that was identified in the corresponding request;
- The signature on the response is valid;
- The identity of the signer matches the intended recipient of the request;
- The signer is currently authorized to provide a response for the certificate in question;
- The time at which the status being indicated is known to be correct (thisUpdate) is sufficiently recent;
- 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