# How to Read the Signer's Certificate from Verified PDF Signatures in C# (X.509, eIDAS, Chain)
A contract lands in your audit pipeline. It is digitally signed, the signature is valid, and your compliance team needs answers: who signed it, was their certificate valid that morning, and does the issuing CA match your trusted list? You could pull the raw signature bytes, parse the DER, and walk the certificate chain by hand. Or you could ask the `VerifiedSignature` object for its `SignerCertificate` and read the answers off as properties.
That is what the `SignerCertificate` and `CertificateChain` properties on [`VerifiedSignature`](https://ironpdf.com/object-reference/api/IronPdf.Signing.Inspection.VerifiedSignature.html) are built for. Returned from [`PdfDocument.GetVerifiedSignatures()`](https://ironpdf.com/how-to/signing/), they expose the signer's full X.509 identity, the issuing CA, validity dates, the SHA-256 thumbprint, the raw DER bytes, and every intermediate certificate up to the root. That is the API surface you need for eIDAS compliance, certificate pinning, audit trails, and chain-of-trust verification.
This guide walks through three families of certificate inspection:
- **Standard X.509 details:** identity properties, full Distinguished Names, validity windows, and raw DER bytes for `X509Certificate2` interop.
- **eIDAS and regulated-industry fields:** pulling the signer's national ID from `SubjectSerialNumber` and reading numeric OIDs like `2.5.4.97` for the eIDAS organizationIdentifier.
- **Trust-chain validation:** SHA-256 thumbprint pinning and walking the full chain from signer to root CA.
[Start a free 30-day trial](https://ironpdf.com/#trial-license) to test certificate inspection in your verification pipeline.
!!!--LIBRARY_NUGET_INSTALL_BLOCK--!!!
*as-heading:2(Quickstart: Read the Signer's Certificate from a Signed PDF)*
Call `GetVerifiedSignatures` on a loaded PDF and read the signer's certificate properties directly off the result.
```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>Minimal Workflow (3 steps)</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>Load a signed PDF and call <code>GetVerifiedSignatures()</code> to get a list of verified signature objects</li>
<li>Read <code>sig.SignerCertificate</code> for identity and validity, or walk <code>sig.CertificateChain</code> for the full trust chain</li>
</ol>
</div>
<br class="clear" />
## How Do You Extract the Signer's National or Personal ID?
The `SubjectSerialNumber` property returns the value of the SERIALNUMBER OID from the certificate's Subject DN. In regulated industries (eIDAS qualified certificates, banking, government-issued digital IDs), this field carries the signer's national ID, tax ID, or personal identification number. It is not the certificate's own serial number; that is `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:(Quick reminder on the difference between these two: `SubjectSerialNumber` tells you *who* signed the document (a person or organization ID, like a national ID or tax number embedded in the Subject DN). `CertificateSerialNumber` tells you *which certificate* was used; it is the unique serial the issuing Certificate Authority assigns for revocation lists and audit logs.)]]
## How Do You Access Convenience Identity Properties?
`SignerCertificateInfo` exposes the most commonly needed Subject DN fields as direct properties, so you do not need to parse the full DN string yourself.
#### Reading the Signer's Name and Affiliation
The `CommonName`, `Organization`, `Country`, and `Email` properties cover what most identity workflows reach for first.
```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}");
}
```
The `Email` property first checks the Subject DN for the `emailAddress` OID. If not present, it falls back to the Subject Alternative Name (SAN) `rfc822Name` extension. The `Country` property returns the two-letter ISO 3166-1 alpha-2 code (for example, "DE", "US", "FR"). All convenience properties return `null` if the corresponding field is not present in the certificate.
#### Reading the Full DN When You Need Everything
For audit logging, downstream parsing, or compliance reports, `SubjectDN` and `IssuerDN` return the complete Distinguished Name strings.
```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}");
}
```
## How Do You Extract Arbitrary Subject and Issuer Fields?
The `GetSubjectField(string)` and `GetIssuerField(string)` methods accept either short names or numeric OIDs. They are case-insensitive and return `null` if the field is not present.
Supported short names: `CN`, `O`, `OU`, `C`, `L`, `ST`, `E`, `SERIALNUMBER`, `SN`/`SURNAME`, `T`, `GIVENNAME`, `UID`, `ORGANIZATIONIDENTIFIER`.
#### Reading Any Subject Field (Including eIDAS OIDs)
Pass a short name like `"OU"` or a numeric OID like `"2.5.4.97"` (the eIDAS organizationIdentifier) to pull any field from the Subject DN.
```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"}");
}
```
The numeric OID lookup is essential for eIDAS and regulated-industry certificates that embed organization identifiers, professional qualifications, or jurisdiction-specific fields not covered by standard short names.
#### Reading the Issuer's Fields
`GetIssuerField` works the same way against the issuing CA's Distinguished Name. This is useful for trust validation, CA reporting, and grouping signatures by their issuing authority.
```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})");
}
```
## How Do You Check Certificate Validity?
`SignerCertificateInfo` provides two validity helpers:
- `IsExpired` returns `true` if `DateTime.UtcNow > NotAfter`.
- `IsValidAt(DateTime)` returns `true` if the given timestamp falls within the `NotBefore`/`NotAfter` window. The typical use is confirming the certificate was valid at the time of signing.
```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:(`IsExpired` returns `false` (not `true`) when validity dates cannot be extracted from the certificate. The helper is intentionally conservative; it does not assume expiration just because metadata is missing. For zero-trust workflows, treat missing validity dates as a failure case explicitly.)]]
For [audit trails](https://ironpdf.com/how-to/revision-history/), log both the `IsExpired` check (current validity) and the `IsValidAt(signingDate)` check (validity at signing time). A certificate that has since expired may still have been valid when the document was signed; both data points matter for compliance.
## How Do You Use the SHA-256 Thumbprint for Certificate Pinning?
The `Sha256Thumbprint` property returns a 64-character uppercase hex string, the SHA-256 hash of the DER-encoded certificate. This is the value you pin against a known-good list of accepted signer certificates.
```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}");
}
```
## How Do You Construct an X509Certificate2 from Raw Certificate Data?
The `RawData` property returns the DER-encoded certificate as a `byte[]`. Each call returns a defensive copy, so the internal data is never exposed by reference. You can use this to construct a `System.Security.Cryptography.X509Certificates.X509Certificate2` for interop with .NET's native cryptographic APIs (chain building, policy validation, CRL checking).
```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:(Each access to `RawData` returns a fresh defensive copy. The internal byte array is never exposed by reference, so mutating the returned bytes will not affect later calls.)]]
This interop path lets you plug IronPDF's signature verification into existing .NET certificate validation pipelines, such as [`X509Chain.Build()`](https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509chain.build), revocation checking via CRL/OCSP, or custom `X509CertificateValidator` implementations.
## How Do You Walk the Certificate Chain?
The `CertificateChain` property on `VerifiedSignature` returns an `IReadOnlyList<SignerCertificateInfo>` ordered from signer → intermediate CA(s) → root CA. Index 0 is always the signer certificate (the same object as `SignerCertificate`). The list is never null; if the chain cannot be extracted, it contains only the signer certificate.
```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:(Each `SignerCertificateInfo` in the chain exposes the same properties as `SignerCertificate`: identity fields, validity, thumbprint, `RawData`, `GetSubjectField()`, and `GetIssuerField()`. You can validate every intermediate CA's expiration, check the root's thumbprint against your trusted root store, and log the full chain for compliance audits.)]]
## Next Steps
`SignerCertificate` and `CertificateChain` give you full X.509 inspection without leaving the IronPDF API surface. From here, the natural next moves are deeper into the parts of IronPDF these properties plug into.
For the signing side of the workflow, the [digital signatures how-to](https://ironpdf.com/how-to/signing/) covers certificate creation, metadata, and incremental signing. For HSM-based signing in high-security environments, the [HSM signing guide](https://ironpdf.com/how-to/signing-pdf-with-hsm/) covers PKCS#11 integration. Need ready-to-run snippets? The [digital signatures code example](https://ironpdf.com/examples/digitally-sign-a-pdf/) provides them.
Ready to try it on your own signed PDFs? [Start your free 30-day trial](https://ironpdf.com/#trial-license) or [view licensing options](https://ironpdf.com/licensing/).
A contract lands in your audit pipeline. It is digitally signed, the signature is valid, and your compliance team needs answers: who signed it, was their certificate valid that morning, and does the issuing CA match your trusted list? You could pull the raw signature bytes, parse the DER, and walk the certificate chain by hand. Or you could ask the VerifiedSignature object for its SignerCertificate and read the answers off as properties.
That is what the SignerCertificate and CertificateChain properties on VerifiedSignature are built for. Returned from PdfDocument.GetVerifiedSignatures(), they expose the signer's full X.509 identity, the issuing CA, validity dates, the SHA-256 thumbprint, the raw DER bytes, and every intermediate certificate up to the root. That is the API surface you need for eIDAS compliance, certificate pinning, audit trails, and chain-of-trust verification.
This guide walks through three families of certificate inspection:
Standard X.509 details: identity properties, full Distinguished Names, validity windows, and raw DER bytes for X509Certificate2 interop.
eIDAS and regulated-industry fields: pulling the signer's national ID from SubjectSerialNumber and reading numeric OIDs like 2.5.4.97 for the eIDAS organizationIdentifier.
Trust-chain validation: SHA-256 thumbprint pinning and walking the full chain from signer to root CA.
Install IronPDF by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.
Quickstart: Read the Signer's Certificate from a Signed PDF
Call GetVerifiedSignatures on a loaded PDF and read the signer's certificate properties directly off the result.
1Install IronPDF with NuGet Package Manager
PM > Install-Package IronPdf
Install-Package IronPdf
2Copy and run this code snippet.
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}");
C#
3Deploy to test on your live environment
Start using IronPDF in your project today with a free trial
Load a signed PDF and call GetVerifiedSignatures() to get a list of verified signature objects
Read sig.SignerCertificate for identity and validity, or walk sig.CertificateChain for the full trust chain
How Do You Extract the Signer's National or Personal ID?
The SubjectSerialNumber property returns the value of the SERIALNUMBER OID from the certificate's Subject DN. In regulated industries (eIDAS qualified certificates, banking, government-issued digital IDs), this field carries the signer's national ID, tax ID, or personal identification number. It is not the certificate's own serial number; that is 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 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
Tips: Quick reminder on the difference between these two: SubjectSerialNumber tells you who signed the document (a person or organization ID, like a national ID or tax number embedded in the Subject DN). CertificateSerialNumber tells you which certificate was used; it is the unique serial the issuing Certificate Authority assigns for revocation lists and audit logs.
How Do You Access Convenience Identity Properties?
SignerCertificateInfo exposes the most commonly needed Subject DN fields as direct properties, so you do not need to parse the full DN string yourself.
Reading the Signer's Name and Affiliation
The CommonName, Organization, Country, and Email properties cover what most identity workflows reach for first.
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
The Email property first checks the Subject DN for the emailAddress OID. If not present, it falls back to the Subject Alternative Name (SAN) rfc822Name extension. The Country property returns the two-letter ISO 3166-1 alpha-2 code (for example, "DE", "US", "FR"). All convenience properties return null if the corresponding field is not present in the certificate.
Reading the Full DN When You Need Everything
For audit logging, downstream parsing, or compliance reports, SubjectDN and IssuerDN return the complete Distinguished Name strings.
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
How Do You Extract Arbitrary Subject and Issuer Fields?
The GetSubjectField(string) and GetIssuerField(string) methods accept either short names or numeric OIDs. They are case-insensitive and return null if the field is not present.
Supported short names: CN, O, OU, C, L, ST, E, SERIALNUMBER, SN/SURNAME, T, GIVENNAME, UID, ORGANIZATIONIDENTIFIER.
Reading Any Subject Field (Including eIDAS OIDs)
Pass a short name like "OU" or a numeric OID like "2.5.4.97" (the eIDAS organizationIdentifier) to pull any field from the Subject DN.
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
The numeric OID lookup is essential for eIDAS and regulated-industry certificates that embed organization identifiers, professional qualifications, or jurisdiction-specific fields not covered by standard short names.
Reading the Issuer's Fields
GetIssuerField works the same way against the issuing CA's Distinguished Name. This is useful for trust validation, CA reporting, and grouping signatures by their issuing authority.
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
My favorite library of this kind is IronPDF. It allows for fast and efficient manipulation of PDF files. It also has many valuable features, like exporting to PDF/A format and digitally signing PDF documents.
IronOCR means we can save $40,000 annually from manual processing, while enhancing productivity and freeing up resources for high-impact tasks. I would highly recommend it.
SignerCertificateInfo provides two validity helpers:
IsExpired returns true if DateTime.UtcNow > NotAfter.
IsValidAt(DateTime) returns true if the given timestamp falls within the NotBefore/NotAfter window. The typical use is confirming the certificate was valid at the time of signing.
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
Tips: IsExpired returns false (not true) when validity dates cannot be extracted from the certificate. The helper is intentionally conservative; it does not assume expiration just because metadata is missing. For zero-trust workflows, treat missing validity dates as a failure case explicitly.
For audit trails, log both the IsExpired check (current validity) and the IsValidAt(signingDate) check (validity at signing time). A certificate that has since expired may still have been valid when the document was signed; both data points matter for compliance.
How Do You Use the SHA-256 Thumbprint for Certificate Pinning?
The Sha256Thumbprint property returns a 64-character uppercase hex string, the SHA-256 hash of the DER-encoded certificate. This is the value you pin against a known-good list of accepted signer certificates.
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
How Do You Construct an X509Certificate2 from Raw Certificate Data?
The RawData property returns the DER-encoded certificate as a byte[]. Each call returns a defensive copy, so the internal data is never exposed by reference. You can use this to construct a System.Security.Cryptography.X509Certificates.X509Certificate2 for interop with .NET's native cryptographic APIs (chain building, policy validation, CRL checking).
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
Please note: Each access to RawData returns a fresh defensive copy. The internal byte array is never exposed by reference, so mutating the returned bytes will not affect later calls.
This interop path lets you plug IronPDF's signature verification into existing .NET certificate validation pipelines, such as X509Chain.Build(), revocation checking via CRL/OCSP, or custom X509CertificateValidator implementations.
How Do You Walk the Certificate Chain?
The CertificateChain property on VerifiedSignature returns an IReadOnlyList<SignerCertificateInfo> ordered from signer → intermediate CA(s) → root CA. Index 0 is always the signer certificate (the same object as SignerCertificate). The list is never null; if the chain cannot be extracted, it contains only the signer certificate.
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
Please note: Each SignerCertificateInfo in the chain exposes the same properties as SignerCertificate: identity fields, validity, thumbprint, RawData, GetSubjectField(), and GetIssuerField(). You can validate every intermediate CA's expiration, check the root's thumbprint against your trusted root store, and log the full chain for compliance audits.
Next Steps
SignerCertificate and CertificateChain give you full X.509 inspection without leaving the IronPDF API surface. From here, the natural next moves are deeper into the parts of IronPDF these properties plug into.
For the signing side of the workflow, the digital signatures how-to covers certificate creation, metadata, and incremental signing. For HSM-based signing in high-security environments, the HSM signing guide covers PKCS#11 integration. Need ready-to-run snippets? The digital signatures code example provides them.
What is the `SignerCertificate` property used for in IronPDF?
The `SignerCertificate` property in IronPDF is used to extract detailed X.509 certificate information from a verified PDF signature, such as the signer's identity, issuing Certificate Authority, validity dates, and other related properties.
How can I validate the certificate chain using IronPDF?
In IronPDF, you can validate the certificate chain using the `CertificateChain` property on the `VerifiedSignature` object. This provides an ordered list of certificates from the signer to the root CA for chain-of-trust verification.
What types of certificate details can be extracted with IronPDF?
IronPDF allows you to extract standard X.509 certificate details, eIDAS fields, trust-chain validation information, as well as properties like the common name, organization, thumbprint, and validity dates.
Can IronPDF handle eIDAS specific fields?
Yes, IronPDF can handle eIDAS specific fields by accessing the `SubjectSerialNumber` and numeric OIDs like `2.5.4.97` to pull information such as national IDs from qualified certificates.
How does IronPDF assist in verifying if a certificate was valid at signing?
IronPDF provides the `IsValidAt(DateTime)` method in the `SignerCertificateInfo` class to check if the certificate was valid at the time of signing, which is crucial for compliance verification.
Is it possible to pin a certificate using its SHA-256 thumbprint with IronPDF?
Yes, IronPDF allows you to use the `Sha256Thumbprint` property to retrieve a certificate's thumbprint, which can then be compared against a known-good list for certificate pinning purposes.
How can I construct an `X509Certificate2` object for further use in .NET from IronPDF?
IronPDF's `SignerCertificate` exposes a `RawData` property that provides DER-encoded certificate bytes, which can be used to initialize a `System.Security.Cryptography.X509Certificates.X509Certificate2` object for further cryptographic operations.
Does IronPDF provide methods to read arbitrary certificate fields?
Yes, IronPDF provides `GetSubjectField(string)` and `GetIssuerField(string)` methods to access arbitrary fields from a certificate using standard names or numeric OIDs.
How does IronPDF ensure data security when accessing raw certificate data?
IronPDF ensures data security by providing a defensive copy of raw certificate data through the `RawData` property, ensuring the internal data is never exposed by reference.
What is the purpose of the `CertificateChain` property in IronPDF?
The `CertificateChain` property in IronPDF returns an ordered list of certificates from the signer to the root CA, allowing for trust chain evaluation and audit trails.
Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.