【发布时间】:2017-09-27 15:48:54
【问题描述】:
我正在尝试使用 iTextSharp 在 c# 中验证数字签名。
我已按照 iText 网络 (http://gitlab.itextsupport.com/itextsharp/tutorial/blob/master/signatures/chapter5/C5_03_CertificateValidation/C5_03_CertificateValidation.cs) 中的示例进行操作,但结果并非我所期望的。具体来说,当尝试通过 OCSP 或 CRL 验证签名时,结果通常是无法验证签名。我认为这不应该发生,因为 Adobe Reader 可以验证签名。
我用来测试验证的 pdf 可以在这个链接中找到:https://blogs.adobe.com/security/SampleSignedPDFDocument.pdf
这是我正在使用的代码(上面链接中示例的简短版本):
static void Main(String[] args)
{
LoggerFactory.GetInstance().SetLogger(new SysoLogger());
C5_03_CertificateValidation app = new C5_03_CertificateValidation();
app.VerifySignatures(EXAMPLE); //Pdf file I'm using to test the verification
}
public void VerifySignatures(String path)
{
Console.WriteLine(path);
PdfReader reader = new PdfReader(path);
AcroFields fields = reader.AcroFields;
List<String> names = fields.GetSignatureNames();
foreach (string name in names)
{
Console.WriteLine("===== " + name + " =====");
VerifySignature(fields, name);
}
Console.WriteLine();
}
public PdfPKCS7 VerifySignature(AcroFields fields, String name)
{
PdfPKCS7 pkcs7 = fields.VerifySignature(name);
X509Certificate[] certs = pkcs7.SignCertificateChain;
DateTime cal = pkcs7.SignDate;
X509Certificate signCert = certs[0];
X509Certificate issuerCert = (certs.Length > 1 ? certs[1] : null);
Console.WriteLine("=== Checking validity of the document at the time of signing ===");
CheckRevocation(pkcs7, signCert, issuerCert, cal);
Console.WriteLine("=== Checking validity of the document today ===");
CheckRevocation(pkcs7, signCert, issuerCert, DateTime.Now);
return pkcs7;
}
public static void CheckRevocation(PdfPKCS7 pkcs7, X509Certificate signCert, X509Certificate issuerCert, DateTime date)
{
List<BasicOcspResp> ocsps = new List<BasicOcspResp>();
if (pkcs7.Ocsp != null)
ocsps.Add(pkcs7.Ocsp);
OcspVerifier ocspVerifier = new OcspVerifier(null, ocsps);
List<VerificationOK> verification =
ocspVerifier.Verify(signCert, issuerCert, date);
if (verification.Count == 0)
{
List<X509Crl> crls = new List<X509Crl>();
if (pkcs7.CRLs != null)
foreach (X509Crl crl in pkcs7.CRLs)
crls.Add(crl);
CrlVerifier crlVerifier = new CrlVerifier(null, crls);
verification.AddRange(crlVerifier.Verify(signCert, issuerCert, date));
}
if (verification.Count == 0)
Console.WriteLine("The signing certificate couldn't be verified with the example");
else
foreach (VerificationOK v in verification)
Console.WriteLine(v);
//Code not in the example, added by me
//This way, I can find out if the certificate is revoked or not (through CRL). Not sure if it's the right way though
if (verification.Count == 0 && pkcs7.CRLs != null && pkcs7.CRLs.Count != 0)
{
bool revoked = false;
foreach (X509Crl crl in pkcs7.CRLs)
{
revoked = crl.IsRevoked(pkcs7.SigningCertificate);
if (revoked)
break;
}
Console.WriteLine("Is certificate revoked?: " + revoked.ToString());
}
}
这是我得到的输出:
===== Signature2 =====
=== Checking validity of the document at the time of signing ===
i.t.p.s.OcspClientBouncyCastle INFO Getting OCSP from http://adobe-ocsp.geotrust.com/responder
iTextSharp.text.pdf.security.OcspClientBouncyCastle ERROR Error en el servidor remoto: (502) Puerta de enlace no válida.
i.t.p.s.OcspVerifier INFO Valid OCSPs found: 0
i.t.p.s.CrlVerifier INFO Getting CRL from http://crl.geotrust.com/crls/adobeca1.crl
i.t.p.s.CrlVerifier INFO Valid CRLs found: 0
The signing certificate couldnt be verified with the example
Is certificate revoked?: False
=== Checking validity of the document today ===
i.t.p.s.OcspClientBouncyCastle INFO Getting OCSP from http://adobe-ocsp.geotrust.com/responder
iTextSharp.text.pdf.security.OcspClientBouncyCastle ERROR Error en el servidor remoto: (502) Puerta de enlace no válida.
i.t.p.s.OcspVerifier INFO Valid OCSPs found: 0
i.t.p.s.CrlVerifier INFO Getting CRL from http://crl.geotrust.com/crls/adobeca1.crl
i.t.p.s.CrlVerifier INFO Valid CRLs found: 0
The signing certificate couldnt be verified with the example
Is certificate revoked?: False
我不明白为什么无法验证签名,因为 Adobe 可以做到。任何想法都表示赞赏。
【问题讨论】:
-
如果您仔细查看 Adobe Reader 的输出,您会看到“所选证书被认为是有效的,因为它没有出现在 嵌入的证书撤销列表 (CRL) 中签名。”您的代码尝试在线检索 OCSP 响应或 CRL。
-
@mkl 我查过了,你是对的。但是签名也有 OCSP url 和 CRL url(我明白阅读输出),我不明白为什么无法使用这些验证签名。可能是网址无效吗?另外,我不明白为什么 crlVerifier 没有给出答案,但 crl.IsRevoked 给出了答案。 (顺便说一句,感谢您的快速回答)
-
“但签名也有 OCSP url 和 CRL url(我明白阅读输出),我不明白为什么无法使用这些验证签名。” - A OCSP 服务 URL 不再存在;该服务似乎已停止。这就是为什么应该将验证相关信息添加到 PDF 本身的原因。 B 您当前从该 URL 检索到的 CRL 从 2015 年 1 月 22 日开始有效。签名者证书在 2009-09-04 之后被标记为有效。因此,不能从该 CRL 中获得有关证书的可用信息。 ...
-
嵌入到签名中的 CRL 从 2009-07-16 开始有效,即签名创建日期。因此,该 CRL 确实包含有关证书的可用信息。
-
Hhmmm,我刚刚意识到(即使它大部分是真的)上面所说的并不能解释你的测试结果。稍后我会写一些更详细的内容。
标签: c# itext digital-signature