# 如何從已驗證的PDF簽名中讀取簽名者的證書在C#中 (X.509, eIDAS, Chain)
一份合同進入您的審核流程。它是數位簽名的,簽名是有效的,您的合規團隊需要答案:誰簽署了它,他們的證書在那天早上是否有效,發布證書的CA是否符合您信任的列表?您可以提取原始簽名的位元組,解析DER,並手動遍歷證書鏈。 或者你可以詢問`SignerCertificate`並以屬性的形式讀取答案。
這就是<a href="https://ironpdf.com/object-reference/api/IronPdf.Signing.Inspection.VerifiedSignature.html">`CertificateChain`屬性的用途。 從[`PdfDocument.GetVerifiedSignatures()`](https://ironpdf.com/how-to/signing/)返回,它們揭露了簽名者的完整X.509身份、發布CA、有效日期、SHA-256指紋、原始DER位元組,以及所有中間證書直到根證書。 這是您用於eIDAS合規性、證書釘扎、審核記錄和信任鏈驗證的API介面。</a>
本指南介紹三種證書檢查型別:
- **標準X.509詳情:**身份屬性、完整的識別名、有効時間區間及`X509Certificate2`互操作的原始DER位元組。
- **eIDAS和受監管行業的字段:**從`2.5.4.97`以獲取eIDAS的organizationIdentifier。
- **信任鏈驗證:**SHA-256指紋釘扎和從簽名者到根CA的完整鏈路遍歷。
[開始免費30天試用](https://ironpdf.com/#trial-license)以測試在您的驗證流程中的證書檢查。
!!!--LIBRARY_NUGET_INSTALL_BLOCK--!!!
*as-heading:2(快速入門:從簽名的PDF中讀取簽名者的證書)*
在載入的PDF上調用`GetVerifiedSignatures`並直接從結果中讀取簽名者的證書屬性。
```cs
:title=Read certificate details in three lines
var sig = PdfDocument.FromFile("signed.pdf").GetVerifiedSignatures().First();
var cert = sig.SignerCertificate;
Console.WriteLine($"{cert?.CommonName} ({cert?.Organization}) valid until {cert?.NotAfter}");
```
<div class="hsg-featured-snippet">
<h3>最小化工作流程(3個步驟)</h3>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://www.nuget.org/packages/IronPdf/">Download IronPDF from NuGet</a></li>
<li>載入已簽名的PDF並調用<code>GetVerifiedSignatures()</code>以獲取已驗證的簽名物件列表</li>
<li>讀取<code>sig.SignerCertificate</code>以獲取身份和有效性,或遍歷<code>sig.CertificateChain</code>以獲取完整的信任鏈</li>
</ol>
</div>
<br class="clear" />
## 如何提取簽名者的國家ID或個人ID?
`SubjectSerialNumber`屬性從證書的主體識別名中返回SERIALNUMBER OID的值。 在受監管行業(eIDAS合格證書、銀行業、政府發行的數位ID),此字段承載簽名者的國家ID、稅號或個人身份號。 它不是證書本身的序列號; 這是`CertificateSerialNumber`。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("eidas-signed-invoice.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Subject DN SERIALNUMBER OID (national ID, tax ID, etc.)
Console.WriteLine($"Signer Identity (SERIALNUMBER): {cert.SubjectSerialNumber ?? "not present"}");
// Certificate's own serial from the issuing CA
Console.WriteLine($"Certificate Serial (CA-issued): {cert.CertificateSerialNumber}");
}
```
[[t:(快速回顧這兩者之間的區別:`SubjectSerialNumber`告訴你*誰*簽署了文件(人或組織ID,例如嵌入在主體識別名中的國家ID或稅號)。 `CertificateSerialNumber`告訴你使用了*哪份證書*; 它是由發布證書的授權機構分配的唯一序列,用於撤銷列表和審核日誌。)]]
## 如何存取便利的身份屬性?
`SignerCertificateInfo`將最常需要的主體識別名字段暴露為直接屬性,因此您無需自己解析完整的識別名字串。
#### 讀取簽名者的姓名和附屬關係
`Email`屬性涵蓋了大多數身份工作流程首選的內容。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("signed-agreement.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Common Subject DN fields exposed directly as properties
Console.WriteLine($"CommonName (CN): {cert.CommonName}");
Console.WriteLine($"Organization (O): {cert.Organization}");
Console.WriteLine($"Country (C): {cert.Country}");
Console.WriteLine($"Email: {cert.Email}");
}
```
`emailAddress` OID。 如果不存在,它回退到主體替代名稱(SAN)`rfc822Name`擴展名。 `Country`屬性返回兩個字母的ISO 3166-1 alpha-2程式碼(例如,"DE"、"US"、"FR")。 如果證書中沒有相應的字段,所有便利屬性均返回`null`。
#### 當您需要完整內容時讀取完整識別名
對於審核日誌、下游解析或合規報告,`IssuerDN`返回完整的識別名字串。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("signed-agreement.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Full DN strings for audit logging or downstream parsing
Console.WriteLine($"Full Subject DN: {cert.SubjectDN}");
Console.WriteLine($"Full Issuer DN: {cert.IssuerDN}");
}
```
## 如何提取任意的主體和發布者字段?
`GetIssuerField(string)`方法可以接受簡短名稱或數字OID。 它們是不區分大小寫的,如果字段不存在,返回`null`。
支持的簡短名稱:`ORGANIZATIONIDENTIFIER`。
#### 讀取任何主體字段(包括eIDAS的OID)
傳遞像`"2.5.4.97"`(eIDAS的organizationIdentifier)以從主體識別名中提取任何字段。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("eidas-contract.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Short-name lookups (case-insensitive)
string? orgUnit = cert.GetSubjectField("OU");
string? surname = cert.GetSubjectField("SURNAME");
string? givenName = cert.GetSubjectField("GIVENNAME");
string? title = cert.GetSubjectField("T");
// Numeric OID lookup (eIDAS organizationIdentifier)
string? orgId = cert.GetSubjectField("2.5.4.97");
Console.WriteLine($"Name: {givenName} {surname} ({title}), OU: {orgUnit}");
Console.WriteLine($"eIDAS Org ID (2.5.4.97): {orgId ?? "not present"}");
}
```
數字OID查找對於嵌入組織標識符、專業資格或不在標準簡短名稱覆蓋範圍內的受司法管轄的字段的eIDAS和受監管行業證書至關重要。
#### 讀取發行者的字段
`GetIssuerField`在發布CA的識別名上以相同方式工作。 這對於信任驗證、CA報告以及按發佈授權組織分組簽名很有用。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("eidas-contract.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// GetIssuerField works the same way as GetSubjectField
string? issuerCN = cert.GetIssuerField("CN");
string? issuerO = cert.GetIssuerField("O");
string? issuerCountry = cert.GetIssuerField("C");
Console.WriteLine($"Issued by: {issuerCN} ({issuerO}, {issuerCountry})");
}
```
## 如何檢查證書有效性?
`SignerCertificateInfo`提供兩個有效性幫助工具:
- `DateTime.UtcNow > NotAfter`。
- `NotAfter`窗口中。 典型的用途是確認證書在簽名時有效。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("archived-contract.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
Console.WriteLine($"Valid from: {cert.NotBefore}");
Console.WriteLine($"Valid until: {cert.NotAfter}");
Console.WriteLine($"Expired now: {cert.IsExpired}");
// Confirm certificate was valid when the document was signed
bool validAtSigning = cert.IsValidAt(sig.SigningDate);
Console.WriteLine($"Valid at signing time ({sig.SigningDate}): {validAtSigning}");
}
```
[[t:(當無法從證書中提取有效性日期時,`true`)。 幫助工具故意保守;它不假設只是因為缺少元資料就過期。 對於零信任工作流程,對待缺少有效性日期作為故障案例來顯式處理。)]]
對於[審核日誌](https://ironpdf.com/how-to/revision-history/),記錄`IsValidAt(signingDate)`檢查(簽名時的有效性)。 自此過期的證書在文件簽署時可能仍然有效; 這兩個資料點對於合規都很重要。
## 如何使用SHA-256指紋進行證書釘扎?
`Sha256Thumbprint`屬性返回一個64個字元的全大寫十六進制字串,是DER編碼證書的SHA-256哈希值。 這是您釘在已知良好接受的簽名者證書清單上的值。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
using System.Collections.Generic;
// Known-good signer thumbprints from a compliance database
var pinnedThumbprints = new HashSet<string>
{
"A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2",
"F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5"
};
var pdf = PdfDocument.FromFile("submitted-form.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Pin against trusted thumbprint list
bool trusted = pinnedThumbprints.Contains(cert.Sha256Thumbprint);
Console.WriteLine($"Signer: {cert.CommonName}, Thumbprint: {cert.Sha256Thumbprint}");
Console.WriteLine($"Pinned: {trusted}");
}
```
## 如何從原始證書資料構建X509Certificate2?
`byte[]`。 每次調用返回一個防禦性副本,因此內部資料決不通過引用暴露。 您可以使用此構建一個`System.Security.Cryptography.X509Certificates.X509Certificate2`以便與.NET的本地密碼API進行互操作(鏈構建、政策驗證、CRL檢查)。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
using System.Security.Cryptography.X509Certificates;
var pdf = PdfDocument.FromFile("signed-report.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Construct X509Certificate2 from defensive DER copy
byte[] derBytes = cert.RawData;
var x509 = new X509Certificate2(derBytes);
Console.WriteLine($"X509 Subject: {x509.Subject}");
Console.WriteLine($"X509 Issuer: {x509.Issuer}");
Console.WriteLine($"X509 Serial: {x509.SerialNumber}");
Console.WriteLine($"X509 Algorithm: {x509.SignatureAlgorithm.FriendlyName}");
Console.WriteLine($"X509 Key Size: {x509.PublicKey.Key.KeySize} bits");
}
```
[[i:(對`RawData`的每次存取都返回一個新的防禦性副本。 內部字節陣列從不通過引用暴露,因此修改返回的字節不會影響以後的調用。)]]
此互操作路徑讓您能夠將IronPDF的簽名驗證插入到現有的.NET證書驗證流水線中,如<a href="https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509chain.build">`X509CertificateValidator`實現。</a>
## 如何遍歷證書鏈?
`IReadOnlyList<SignerCertificateInfo>`,按順序從簽名者→中間CA(s)→根CA排列。 索引0始終是簽名者證書(與`SignerCertificate`相同的物件)。 列表永遠不為空; 如果無法提取鏈,則僅包含簽名者證書。
```csharp
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("enterprise-signed.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
Console.WriteLine($"--- Signature: {sig.SignatureName} ---");
Console.WriteLine($"Chain length: {sig.CertificateChain.Count}");
// Walk from signer (index 0) through intermediates to root CA
for (int i = 0; i < sig.CertificateChain.Count; i++)
{
var cert = sig.CertificateChain[i];
string role = i == 0 ? "Signer"
: i == sig.CertificateChain.Count - 1 ? "Root CA"
: $"Intermediate CA ({i})";
Console.WriteLine($" [{role}]");
Console.WriteLine($" Subject: {cert.SubjectDN}");
Console.WriteLine($" Issuer: {cert.IssuerDN}");
Console.WriteLine($" Serial: {cert.CertificateSerialNumber}");
Console.WriteLine($" Valid: {cert.NotBefore} to {cert.NotAfter}");
Console.WriteLine($" Expired: {cert.IsExpired}");
Console.WriteLine($" Thumbprint: {cert.Sha256Thumbprint}");
}
}
```
[[i:(鏈中的每個`GetIssuerField()`。 您可以驗證每個中間CA的過期,對照您的受信根儲存檢查根的指紋,並記錄完整鏈以進行合規審核。)]]
## 下一步
`CertificateChain`讓您在不離開IronPDF API介面的情況下進行完整的X.509檢查。 從這裡,自然的下一步是更深入地進入這些屬性插入的IronPDF的各個部分。
對於工作流程的簽名部分,[數位簽名使用指南](https://ironpdf.com/how-to/signing/)涵蓋證書建立、元資料和增量簽名。 對於高安全性環境中的HSM簽名,[HSM簽名指南](https://ironpdf.com/how-to/signing-pdf-with-hsm/)涵蓋PKCS#11整合。 需要準備好的運行片段嗎? [數位簽名程式碼範例](https://ironpdf.com/examples/digitally-sign-a-pdf/)提供了這些片段。
準備好自己在已簽名的PDF上進行嘗試了嗎? [開始您的免費30天試用](https://ironpdf.com/#trial-license)或[查看授權選項](https://ironpdf.com/licensing/)。
Install IronPDF by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.
快速入門:從簽名的PDF中讀取簽名者的證書
在載入的PDF上調用GetVerifiedSignatures並直接從結果中讀取簽名者的證書屬性。
1Install IronPDF with NuGet Package Manager
PM > Install-Package IronPdf
Install-Package IronPdf
2複製並運行這段程式碼片段。
var sig = PdfDocument.FromFile("signed.pdf").GetVerifiedSignatures().First();var cert = sig.SignerCertificate;Console.WriteLine($"{cert?.CommonName} ({cert?.Organization}) valid until {cert?.NotAfter}");
var sig = PdfDocument.FromFile("signed.pdf").GetVerifiedSignatures().First();
var cert = sig.SignerCertificate;
Console.WriteLine($"{cert?.CommonName} ({cert?.Organization}) valid until {cert?.NotAfter}");
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("eidas-signed-invoice.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // Subject DN SERIALNUMBER OID (national ID, tax ID, etc.)Console.WriteLine($"Signer Identity (SERIALNUMBER): {cert.SubjectSerialNumber ?? "not present"}"); // Certificate's own serial from the issuing CAConsole.WriteLine($"Certificate Serial (CA-issued): {cert.CertificateSerialNumber}");}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("eidas-signed-invoice.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Subject DN SERIALNUMBER OID (national ID, tax ID, etc.)
Console.WriteLine($"Signer Identity (SERIALNUMBER): {cert.SubjectSerialNumber ?? "not present"}");
// Certificate's own serial from the issuing CA
Console.WriteLine($"Certificate Serial (CA-issued): {cert.CertificateSerialNumber}");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("eidas-signed-invoice.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' Subject DN SERIALNUMBER OID (national ID, tax ID, etc.)Console.WriteLine($"Signer Identity (SERIALNUMBER): {If(cert.SubjectSerialNumber, "not present")}") ' Certificate's own serial from the issuing CAConsole.WriteLine($"Certificate Serial (CA-issued): {cert.CertificateSerialNumber}")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("eidas-signed-invoice.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' Subject DN SERIALNUMBER OID (national ID, tax ID, etc.)
Console.WriteLine($"Signer Identity (SERIALNUMBER): {If(cert.SubjectSerialNumber, "not present")}")
' Certificate's own serial from the issuing CA
Console.WriteLine($"Certificate Serial (CA-issued): {cert.CertificateSerialNumber}")
Next
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("signed-agreement.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // Common Subject DN fields exposed directly as propertiesConsole.WriteLine($"CommonName (CN): {cert.CommonName}");Console.WriteLine($"Organization (O): {cert.Organization}");Console.WriteLine($"Country (C): {cert.Country}");Console.WriteLine($"Email: {cert.Email}");}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("signed-agreement.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Common Subject DN fields exposed directly as properties
Console.WriteLine($"CommonName (CN): {cert.CommonName}");
Console.WriteLine($"Organization (O): {cert.Organization}");
Console.WriteLine($"Country (C): {cert.Country}");
Console.WriteLine($"Email: {cert.Email}");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("signed-agreement.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' Common Subject DN fields exposed directly as propertiesConsole.WriteLine($"CommonName (CN): {cert.CommonName}")Console.WriteLine($"Organization (O): {cert.Organization}")Console.WriteLine($"Country (C): {cert.Country}")Console.WriteLine($"Email: {cert.Email}")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("signed-agreement.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' Common Subject DN fields exposed directly as properties
Console.WriteLine($"CommonName (CN): {cert.CommonName}")
Console.WriteLine($"Organization (O): {cert.Organization}")
Console.WriteLine($"Country (C): {cert.Country}")
Console.WriteLine($"Email: {cert.Email}")
Next
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("signed-agreement.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // Full DN strings for audit logging or downstream parsingConsole.WriteLine($"Full Subject DN: {cert.SubjectDN}");Console.WriteLine($"Full Issuer DN: {cert.IssuerDN}");}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("signed-agreement.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Full DN strings for audit logging or downstream parsing
Console.WriteLine($"Full Subject DN: {cert.SubjectDN}");
Console.WriteLine($"Full Issuer DN: {cert.IssuerDN}");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("signed-agreement.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' Full DN strings for audit logging or downstream parsingConsole.WriteLine($"Full Subject DN: {cert.SubjectDN}")Console.WriteLine($"Full Issuer DN: {cert.IssuerDN}")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("signed-agreement.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' Full DN strings for audit logging or downstream parsing
Console.WriteLine($"Full Subject DN: {cert.SubjectDN}")
Console.WriteLine($"Full Issuer DN: {cert.IssuerDN}")
Next
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("eidas-contract.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // Short-name lookups (case-insensitive) string? orgUnit = cert.GetSubjectField("OU"); string? surname = cert.GetSubjectField("SURNAME"); string? givenName = cert.GetSubjectField("GIVENNAME"); string? title = cert.GetSubjectField("T"); // Numeric OID lookup (eIDAS organizationIdentifier) string? orgId = cert.GetSubjectField("2.5.4.97");Console.WriteLine($"Name: {givenName} {surname} ({title}), OU: {orgUnit}");Console.WriteLine($"eIDAS Org ID (2.5.4.97): {orgId ?? "not present"}");}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("eidas-contract.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Short-name lookups (case-insensitive)
string? orgUnit = cert.GetSubjectField("OU");
string? surname = cert.GetSubjectField("SURNAME");
string? givenName = cert.GetSubjectField("GIVENNAME");
string? title = cert.GetSubjectField("T");
// Numeric OID lookup (eIDAS organizationIdentifier)
string? orgId = cert.GetSubjectField("2.5.4.97");
Console.WriteLine($"Name: {givenName} {surname} ({title}), OU: {orgUnit}");
Console.WriteLine($"eIDAS Org ID (2.5.4.97): {orgId ?? "not present"}");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("eidas-contract.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' Short-name lookups (case-insensitive) Dim orgUnit AsString = cert.GetSubjectField("OU") Dim surname AsString = cert.GetSubjectField("SURNAME") Dim givenName AsString = cert.GetSubjectField("GIVENNAME") Dim title AsString = cert.GetSubjectField("T") ' Numeric OID lookup (eIDAS organizationIdentifier) Dim orgId AsString = cert.GetSubjectField("2.5.4.97")Console.WriteLine($"Name: {givenName} {surname} ({title}), OU: {orgUnit}")Console.WriteLine($"eIDAS Org ID (2.5.4.97): {If(orgId, "not present")}")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("eidas-contract.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' Short-name lookups (case-insensitive)
Dim orgUnit As String = cert.GetSubjectField("OU")
Dim surname As String = cert.GetSubjectField("SURNAME")
Dim givenName As String = cert.GetSubjectField("GIVENNAME")
Dim title As String = cert.GetSubjectField("T")
' Numeric OID lookup (eIDAS organizationIdentifier)
Dim orgId As String = cert.GetSubjectField("2.5.4.97")
Console.WriteLine($"Name: {givenName} {surname} ({title}), OU: {orgUnit}")
Console.WriteLine($"eIDAS Org ID (2.5.4.97): {If(orgId, "not present")}")
Next
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("eidas-contract.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // GetIssuerField works the same way as GetSubjectField string? issuerCN = cert.GetIssuerField("CN"); string? issuerO = cert.GetIssuerField("O"); string? issuerCountry = cert.GetIssuerField("C");Console.WriteLine($"Issued by: {issuerCN} ({issuerO}, {issuerCountry})");}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("eidas-contract.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// GetIssuerField works the same way as GetSubjectField
string? issuerCN = cert.GetIssuerField("CN");
string? issuerO = cert.GetIssuerField("O");
string? issuerCountry = cert.GetIssuerField("C");
Console.WriteLine($"Issued by: {issuerCN} ({issuerO}, {issuerCountry})");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("eidas-contract.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' GetIssuerField works the same way as GetSubjectField Dim issuerCN AsString = cert.GetIssuerField("CN") Dim issuerO AsString = cert.GetIssuerField("O") Dim issuerCountry AsString = cert.GetIssuerField("C")Console.WriteLine($"Issued by: {issuerCN} ({issuerO}, {issuerCountry})")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("eidas-contract.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' GetIssuerField works the same way as GetSubjectField
Dim issuerCN As String = cert.GetIssuerField("CN")
Dim issuerO As String = cert.GetIssuerField("O")
Dim issuerCountry As String = cert.GetIssuerField("C")
Console.WriteLine($"Issued by: {issuerCN} ({issuerO}, {issuerCountry})")
Next
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("archived-contract.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue;Console.WriteLine($"Valid from: {cert.NotBefore}");Console.WriteLine($"Valid until: {cert.NotAfter}");Console.WriteLine($"Expired now: {cert.IsExpired}"); // Confirm certificate was valid when the document was signed bool validAtSigning = cert.IsValidAt(sig.SigningDate);Console.WriteLine($"Valid at signing time ({sig.SigningDate}): {validAtSigning}");}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("archived-contract.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
Console.WriteLine($"Valid from: {cert.NotBefore}");
Console.WriteLine($"Valid until: {cert.NotAfter}");
Console.WriteLine($"Expired now: {cert.IsExpired}");
// Confirm certificate was valid when the document was signed
bool validAtSigning = cert.IsValidAt(sig.SigningDate);
Console.WriteLine($"Valid at signing time ({sig.SigningDate}): {validAtSigning}");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("archived-contract.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue ForConsole.WriteLine($"Valid from: {cert.NotBefore}")Console.WriteLine($"Valid until: {cert.NotAfter}")Console.WriteLine($"Expired now: {cert.IsExpired}") ' Confirm certificate was valid when the document was signed Dim validAtSigning AsBoolean = cert.IsValidAt(sig.SigningDate)Console.WriteLine($"Valid at signing time ({sig.SigningDate}): {validAtSigning}")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("archived-contract.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
Console.WriteLine($"Valid from: {cert.NotBefore}")
Console.WriteLine($"Valid until: {cert.NotAfter}")
Console.WriteLine($"Expired now: {cert.IsExpired}")
' Confirm certificate was valid when the document was signed
Dim validAtSigning As Boolean = cert.IsValidAt(sig.SigningDate)
Console.WriteLine($"Valid at signing time ({sig.SigningDate}): {validAtSigning}")
Next
using IronPdf;using IronPdf.Signing.Inspection;using System.Collections.Generic;// Known-good signer thumbprints from a compliance databasevar pinnedThumbprints = new HashSet<string>{ "A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2", "F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5"};var pdf = PdfDocument.FromFile("submitted-form.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // Pin against trusted thumbprint list bool trusted = pinnedThumbprints.Contains(cert.Sha256Thumbprint);Console.WriteLine($"Signer: {cert.CommonName}, Thumbprint: {cert.Sha256Thumbprint}");Console.WriteLine($"Pinned: {trusted}");}
using IronPdf;
using IronPdf.Signing.Inspection;
using System.Collections.Generic;
// Known-good signer thumbprints from a compliance database
var pinnedThumbprints = new HashSet<string>
{
"A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2",
"F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5"
};
var pdf = PdfDocument.FromFile("submitted-form.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Pin against trusted thumbprint list
bool trusted = pinnedThumbprints.Contains(cert.Sha256Thumbprint);
Console.WriteLine($"Signer: {cert.CommonName}, Thumbprint: {cert.Sha256Thumbprint}");
Console.WriteLine($"Pinned: {trusted}");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionImportsSystem.Collections.Generic' Known-good signer thumbprints from a compliance databaseDim pinnedThumbprints As New HashSet(OfString) From { "A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2", "F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5"}Dim pdf = PdfDocument.FromFile("submitted-form.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' Pin against trusted thumbprint list Dim trusted AsBoolean = pinnedThumbprints.Contains(cert.Sha256Thumbprint)Console.WriteLine($"Signer: {cert.CommonName}, Thumbprint: {cert.Sha256Thumbprint}")Console.WriteLine($"Pinned: {trusted}")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Imports System.Collections.Generic
' Known-good signer thumbprints from a compliance database
Dim pinnedThumbprints As New HashSet(Of String) From {
"A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2",
"F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5D4C3B2A1F6E5"
}
Dim pdf = PdfDocument.FromFile("submitted-form.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' Pin against trusted thumbprint list
Dim trusted As Boolean = pinnedThumbprints.Contains(cert.Sha256Thumbprint)
Console.WriteLine($"Signer: {cert.CommonName}, Thumbprint: {cert.Sha256Thumbprint}")
Console.WriteLine($"Pinned: {trusted}")
Next
using IronPdf;using IronPdf.Signing.Inspection;using System.Security.Cryptography.X509Certificates;var pdf = PdfDocument.FromFile("signed-report.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){ var cert = sig.SignerCertificate; if (cert is null) continue; // Construct X509Certificate2 from defensive DER copy byte[] derBytes = cert.RawData; var x509 = new X509Certificate2(derBytes);Console.WriteLine($"X509 Subject: {x509.Subject}");Console.WriteLine($"X509 Issuer: {x509.Issuer}");Console.WriteLine($"X509 Serial: {x509.SerialNumber}");Console.WriteLine($"X509 Algorithm: {x509.SignatureAlgorithm.FriendlyName}");Console.WriteLine($"X509 Key Size: {x509.PublicKey.Key.KeySize} bits");}
using IronPdf;
using IronPdf.Signing.Inspection;
using System.Security.Cryptography.X509Certificates;
var pdf = PdfDocument.FromFile("signed-report.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
var cert = sig.SignerCertificate;
if (cert is null) continue;
// Construct X509Certificate2 from defensive DER copy
byte[] derBytes = cert.RawData;
var x509 = new X509Certificate2(derBytes);
Console.WriteLine($"X509 Subject: {x509.Subject}");
Console.WriteLine($"X509 Issuer: {x509.Issuer}");
Console.WriteLine($"X509 Serial: {x509.SerialNumber}");
Console.WriteLine($"X509 Algorithm: {x509.SignatureAlgorithm.FriendlyName}");
Console.WriteLine($"X509 Key Size: {x509.PublicKey.Key.KeySize} bits");
}
ImportsIronPdfImportsIronPdf.Signing.InspectionImportsSystem.Security.Cryptography.X509CertificatesDim pdf = PdfDocument.FromFile("signed-report.pdf")For Each sig In pdf.GetVerifiedSignatures() Dim cert = sig.SignerCertificate If cert Is Nothing Then Continue For ' Construct X509Certificate2 from defensive DER copy Dim derBytes AsByte() = cert.RawData Dim x509 = New X509Certificate2(derBytes)Console.WriteLine($"X509 Subject: {x509.Subject}")Console.WriteLine($"X509 Issuer: {x509.Issuer}")Console.WriteLine($"X509 Serial: {x509.SerialNumber}")Console.WriteLine($"X509 Algorithm: {x509.SignatureAlgorithm.FriendlyName}")Console.WriteLine($"X509 Key Size: {x509.PublicKey.Key.KeySize} bits")Next
Imports IronPdf
Imports IronPdf.Signing.Inspection
Imports System.Security.Cryptography.X509Certificates
Dim pdf = PdfDocument.FromFile("signed-report.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Dim cert = sig.SignerCertificate
If cert Is Nothing Then Continue For
' Construct X509Certificate2 from defensive DER copy
Dim derBytes As Byte() = cert.RawData
Dim x509 = New X509Certificate2(derBytes)
Console.WriteLine($"X509 Subject: {x509.Subject}")
Console.WriteLine($"X509 Issuer: {x509.Issuer}")
Console.WriteLine($"X509 Serial: {x509.SerialNumber}")
Console.WriteLine($"X509 Algorithm: {x509.SignatureAlgorithm.FriendlyName}")
Console.WriteLine($"X509 Key Size: {x509.PublicKey.Key.KeySize} bits")
Next
using IronPdf;using IronPdf.Signing.Inspection;var pdf = PdfDocument.FromFile("enterprise-signed.pdf");foreach (var sig in pdf.GetVerifiedSignatures()){Console.WriteLine($"--- Signature: {sig.SignatureName} ---");Console.WriteLine($"Chain length: {sig.CertificateChain.Count}"); // Walk from signer (index 0) through intermediates to root CA for (int i = 0; i < sig.CertificateChain.Count; i++) { var cert = sig.CertificateChain[i]; string role = i == 0 ? "Signer" : i == sig.CertificateChain.Count - 1 ? "Root CA" : $"Intermediate CA ({i})";Console.WriteLine($" [{role}]");Console.WriteLine($" Subject: {cert.SubjectDN}");Console.WriteLine($" Issuer: {cert.IssuerDN}");Console.WriteLine($" Serial: {cert.CertificateSerialNumber}");Console.WriteLine($" Valid: {cert.NotBefore} to {cert.NotAfter}");Console.WriteLine($" Expired: {cert.IsExpired}");Console.WriteLine($" Thumbprint: {cert.Sha256Thumbprint}"); }}
using IronPdf;
using IronPdf.Signing.Inspection;
var pdf = PdfDocument.FromFile("enterprise-signed.pdf");
foreach (var sig in pdf.GetVerifiedSignatures())
{
Console.WriteLine($"--- Signature: {sig.SignatureName} ---");
Console.WriteLine($"Chain length: {sig.CertificateChain.Count}");
// Walk from signer (index 0) through intermediates to root CA
for (int i = 0; i < sig.CertificateChain.Count; i++)
{
var cert = sig.CertificateChain[i];
string role = i == 0 ? "Signer"
: i == sig.CertificateChain.Count - 1 ? "Root CA"
: $"Intermediate CA ({i})";
Console.WriteLine($" [{role}]");
Console.WriteLine($" Subject: {cert.SubjectDN}");
Console.WriteLine($" Issuer: {cert.IssuerDN}");
Console.WriteLine($" Serial: {cert.CertificateSerialNumber}");
Console.WriteLine($" Valid: {cert.NotBefore} to {cert.NotAfter}");
Console.WriteLine($" Expired: {cert.IsExpired}");
Console.WriteLine($" Thumbprint: {cert.Sha256Thumbprint}");
}
}
ImportsIronPdfImportsIronPdf.Signing.InspectionDim pdf = PdfDocument.FromFile("enterprise-signed.pdf")For Each sig In pdf.GetVerifiedSignatures()Console.WriteLine($"--- Signature: {sig.SignatureName} ---")Console.WriteLine($"Chain length: {sig.CertificateChain.Count}") ' Walk from signer (index 0) through intermediates to root CA For i AsInteger = 0 To sig.CertificateChain.Count - 1 Dim cert = sig.CertificateChain(i) Dim role AsString = If(i = 0, "Signer", If(i = sig.CertificateChain.Count - 1, "Root CA", $"Intermediate CA ({i})"))Console.WriteLine($" [{role}]")Console.WriteLine($" Subject: {cert.SubjectDN}")Console.WriteLine($" Issuer: {cert.IssuerDN}")Console.WriteLine($" Serial: {cert.CertificateSerialNumber}")Console.WriteLine($" Valid: {cert.NotBefore} to {cert.NotAfter}")Console.WriteLine($" Expired: {cert.IsExpired}")Console.WriteLine($" Thumbprint: {cert.Sha256Thumbprint}") NextNext
Imports IronPdf
Imports IronPdf.Signing.Inspection
Dim pdf = PdfDocument.FromFile("enterprise-signed.pdf")
For Each sig In pdf.GetVerifiedSignatures()
Console.WriteLine($"--- Signature: {sig.SignatureName} ---")
Console.WriteLine($"Chain length: {sig.CertificateChain.Count}")
' Walk from signer (index 0) through intermediates to root CA
For i As Integer = 0 To sig.CertificateChain.Count - 1
Dim cert = sig.CertificateChain(i)
Dim role As String = If(i = 0, "Signer", If(i = sig.CertificateChain.Count - 1, "Root CA", $"Intermediate CA ({i})"))
Console.WriteLine($" [{role}]")
Console.WriteLine($" Subject: {cert.SubjectDN}")
Console.WriteLine($" Issuer: {cert.IssuerDN}")
Console.WriteLine($" Serial: {cert.CertificateSerialNumber}")
Console.WriteLine($" Valid: {cert.NotBefore} to {cert.NotAfter}")
Console.WriteLine($" Expired: {cert.IsExpired}")
Console.WriteLine($" Thumbprint: {cert.Sha256Thumbprint}")
Next
Next