使用itext7从pdf中的数字签名中提取电子邮件地址
Extract Email address from a digital signature in pdf using itext7
假设 pdf 是使用 DSC 令牌证书签名的。 Adobe reader 将用户的电子邮件地址提供给 signed.How 我可以使用 itext7 c# 从数字签名中提取电子邮件地址吗?
我尝试在 PdfPKCS7 中提取数据 class.But 它不包含电子邮件地址。
使用 ItextSharp,
PdfReader reader = new PdfReader(path);
AcroFields fields = reader.AcroFields;
List<String> names = fields.GetSignatureNames();
foreach (string name in names)
{
VerifySignature(fields, name);
}
其中验证签名方法提供了证书详细信息
virtual public PdfPKCS7 VerifySignature(AcroFields fields, String name)
{
Console.WriteLine("Signature covers whole document: " + fields.SignatureCoversWholeDocument(name));
Console.WriteLine("Document revision: " + fields.GetRevision(name) + " of " + fields.TotalRevisions);
PdfPKCS7 pkcs7 = fields.VerifySignature(name);
Console.WriteLine("Integrity check OK? " + pkcs7.Verify());
return pkcs7;
}
您的示例 PDF 至少在四个位置包含电子邮件地址:
- 签名值的名称条目。
- 签名者证书的主题备用名称。
- 签名者证书的主题 DN 的公用名。
- 签署者证书的主题 DN 的电子邮件地址。
以下代码对应于您的 iTextSharp 代码加上四个电子邮件地址位置的输出:
using (PdfReader pdfReader = new PdfReader(PDF))
using (PdfDocument pdfDocument = new PdfDocument(pdfReader))
{
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
foreach (string signatureName in signatureUtil.GetSignatureNames())
{
Console.WriteLine("\n{0}\n**********", signatureName);
Console.WriteLine("Name: " + signatureUtil.GetSignature(signatureName).GetName());
Console.WriteLine("Signature covers whole document: " + signatureUtil.SignatureCoversWholeDocument(signatureName));
Console.WriteLine("Document revision: " + signatureUtil.GetRevision(signatureName) + " of " + signatureUtil.GetTotalRevisions());
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(signatureName);
Console.WriteLine("Integrity check OK? " + pkcs7.VerifySignatureIntegrityAndAuthenticity());
Org.BouncyCastle.X509.X509Certificate cert = pkcs7.GetSigningCertificate();
Console.Write("Subject alternative names: ");
foreach (var list in cert.GetSubjectAlternativeNames())
foreach (var name in (IList)list)
Console.Write(name + " ");
Console.WriteLine();
Org.BouncyCastle.Asn1.X509.X509Name subjectDn = cert.SubjectDN;
Console.WriteLine("Subject DN: " + subjectDn);
Console.Write("Subject DN common name: ");
foreach (var name in subjectDn.GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.CN))
Console.Write(name + " ");
Console.WriteLine();
Console.Write("Subject DN email: ");
foreach (var name in subjectDn.GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.EmailAddress))
Console.Write(name + " ");
Console.WriteLine();
}
}
您文件的输出:
Signature1
**********
Name: gerald.holmann@qoppa.com
Signature covers whole document: True
Document revision: 1 of 1
Integrity check OK? True
Subject alternative names: 1 gerald.holmann@qoppa.com
Subject DN: CN=gerald.holmann@qoppa.com,E=gerald.holmann@qoppa.com
Subject DN common name: gerald.holmann@qoppa.com
Subject DN email: gerald.holmann@qoppa.com
我显然无法判断这些位置中的哪些将被您遇到的其他证书使用。因此,您要么必须查明是否在您的要求中指定了某处,要么您可能必须简单地检查所有这些字段。
Adobe Reader 在您指出的位置最有可能显示签名者证书的主题 DN 的通用名称,但这不必是电子邮件地址,它可以是任何用作证书所有者的通用名称。
假设 pdf 是使用 DSC 令牌证书签名的。 Adobe reader 将用户的电子邮件地址提供给 signed.How 我可以使用 itext7 c# 从数字签名中提取电子邮件地址吗?
我尝试在 PdfPKCS7 中提取数据 class.But 它不包含电子邮件地址。
使用 ItextSharp,
PdfReader reader = new PdfReader(path);
AcroFields fields = reader.AcroFields;
List<String> names = fields.GetSignatureNames();
foreach (string name in names)
{
VerifySignature(fields, name);
}
其中验证签名方法提供了证书详细信息
virtual public PdfPKCS7 VerifySignature(AcroFields fields, String name)
{
Console.WriteLine("Signature covers whole document: " + fields.SignatureCoversWholeDocument(name));
Console.WriteLine("Document revision: " + fields.GetRevision(name) + " of " + fields.TotalRevisions);
PdfPKCS7 pkcs7 = fields.VerifySignature(name);
Console.WriteLine("Integrity check OK? " + pkcs7.Verify());
return pkcs7;
}
您的示例 PDF 至少在四个位置包含电子邮件地址:
- 签名值的名称条目。
- 签名者证书的主题备用名称。
- 签名者证书的主题 DN 的公用名。
- 签署者证书的主题 DN 的电子邮件地址。
以下代码对应于您的 iTextSharp 代码加上四个电子邮件地址位置的输出:
using (PdfReader pdfReader = new PdfReader(PDF))
using (PdfDocument pdfDocument = new PdfDocument(pdfReader))
{
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
foreach (string signatureName in signatureUtil.GetSignatureNames())
{
Console.WriteLine("\n{0}\n**********", signatureName);
Console.WriteLine("Name: " + signatureUtil.GetSignature(signatureName).GetName());
Console.WriteLine("Signature covers whole document: " + signatureUtil.SignatureCoversWholeDocument(signatureName));
Console.WriteLine("Document revision: " + signatureUtil.GetRevision(signatureName) + " of " + signatureUtil.GetTotalRevisions());
PdfPKCS7 pkcs7 = signatureUtil.ReadSignatureData(signatureName);
Console.WriteLine("Integrity check OK? " + pkcs7.VerifySignatureIntegrityAndAuthenticity());
Org.BouncyCastle.X509.X509Certificate cert = pkcs7.GetSigningCertificate();
Console.Write("Subject alternative names: ");
foreach (var list in cert.GetSubjectAlternativeNames())
foreach (var name in (IList)list)
Console.Write(name + " ");
Console.WriteLine();
Org.BouncyCastle.Asn1.X509.X509Name subjectDn = cert.SubjectDN;
Console.WriteLine("Subject DN: " + subjectDn);
Console.Write("Subject DN common name: ");
foreach (var name in subjectDn.GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.CN))
Console.Write(name + " ");
Console.WriteLine();
Console.Write("Subject DN email: ");
foreach (var name in subjectDn.GetValueList(Org.BouncyCastle.Asn1.X509.X509Name.EmailAddress))
Console.Write(name + " ");
Console.WriteLine();
}
}
您文件的输出:
Signature1
**********
Name: gerald.holmann@qoppa.com
Signature covers whole document: True
Document revision: 1 of 1
Integrity check OK? True
Subject alternative names: 1 gerald.holmann@qoppa.com
Subject DN: CN=gerald.holmann@qoppa.com,E=gerald.holmann@qoppa.com
Subject DN common name: gerald.holmann@qoppa.com
Subject DN email: gerald.holmann@qoppa.com
我显然无法判断这些位置中的哪些将被您遇到的其他证书使用。因此,您要么必须查明是否在您的要求中指定了某处,要么您可能必须简单地检查所有这些字段。
Adobe Reader 在您指出的位置最有可能显示签名者证书的主题 DN 的通用名称,但这不必是电子邮件地址,它可以是任何用作证书所有者的通用名称。