Comment lire le certificat du signataire à partir de signatures PDF vérifiées en C# (X.509, eIDAS, chaîne)
Un contrat arrive dans votre pipeline d'audit. Il est signé numériquement, la signature est valide, et votre équipe de conformité a besoin de réponses : qui l'a signé, son certificat était-il valide ce matin-là, et l'autorité de certification émettrice figure-t-elle dans votre liste de confiance ? Vous pourriez extraire les octets bruts de la signature, analyser le DER et parcourir la chaîne de certificats à la main. Ou bien, vous pourriez demander à l'objet VerifiedSignature sa SignerCertificate et lire les réponses sous forme de propriétés.
C'est à cela que servent les propriétés SignerCertificate et CertificateChain de VerifiedSignature. Renvoyés depuis PdfDocument.GetVerifiedSignatures(), ils exposent l'identité X.509 complète du signataire, l'autorité de certification émettrice, les dates de validité, l'empreinte SHA-256, les octets DER bruts et tous les certificats intermédiaires jusqu'à la racine. C'est l'interface API dont vous avez besoin pour la conformité eIDAS, le certificate pinning, les pistes d'audit et la vérification de la chaîne de confiance.
Ce guide présente trois catégories d'inspection des certificats :
- Détails standard X.509 : propriétés d'identité, noms distinctifs complets, périodes de validité et octets DER bruts pour l'interopérabilité
X509Certificate2. - Domaines liés à l'eIDAS et aux secteurs réglementés : extraction du numéro d'identification national du signataire à partir de
SubjectSerialNumberet lecture d'OID numériques tels que2.5.4.97pour l'identifiant d'organisation eIDAS. - Validation de la chaîne de confiance : fixation de l'empreinte SHA-256 et parcours de la chaîne complète, du signataire à l'autorité de certification racine.
Commencez un essai gratuit de 30 jours pour tester l'inspection des certificats dans votre pipeline de vérification.
Guide de démarrage rapide : Lire le certificat du signataire à partir d'un PDF signé
Appelez GetVerifiedSignatures sur un PDF chargé et lisez les propriétés du certificat du signataire directement à partir du résultat.
-
Installez IronPDF avec le Gestionnaire de Packages NuGet
PM > Install-Package IronPdf -
Copiez et exécutez cet extrait de code.
var sig = PdfDocument.FromFile("signed.pdf").GetVerifiedSignatures().First(); var cert = sig.SignerCertificate; Console.WriteLine($"{cert?.CommonName} ({cert?.Organization}) valid until {cert?.NotAfter}"); -
Déployez pour tester sur votre environnement de production.
Commencez à utiliser IronPDF dans votre projet dès aujourd'hui avec un essai gratuit
Workflow minimal (3 étapes)
- Télécharger IronPDF depuis NuGet
- Chargez un PDF signé et appelez
GetVerifiedSignatures()pour obtenir une liste d'objets de signature vérifiés - Lire
sig.SignerCertificatepour vérifier l'identité et la validité, ousig.CertificateChainpour la chaîne de confiance complète
Comment extraire le numéro d'identification national ou personnel du signataire ?
La propriété SubjectSerialNumber renvoie la valeur de l'OID SERIALNUMBER à partir du DN du sujet du certificat. Dans les secteurs réglementés (certificats qualifiés eIDAS, secteur bancaire, identités numériques émises par les pouvoirs publics), ce champ contient le numéro d'identité national, le numéro d'identification fiscale ou le numéro d'identification personnel du signataire. Il ne s'agit pas du numéro de série du certificat lui-même ; c'est-à-dire CertificateSerialNumber.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-serial-number.cs
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}");
}
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
SubjectSerialNumber indique qui a signé le document (un identifiant de personne ou d'organisation, tel qu'un numéro d'identité national ou un numéro d'identification fiscale intégré dans le DN du sujet). CertificateSerialNumber vous indique quel certificat a été utilisé ; il s'agit du numéro de série unique attribué par l'autorité de certification émettrice pour les listes de révocation et les journaux d'audit.Comment accéder aux propriétés d'identité de commodité ?
SignerCertificateInfo expose les champs DN de sujet les plus couramment utilisés sous forme de propriétés directes, vous n'avez donc pas besoin d'analyser vous-même la chaîne DN complète.
Lecture du nom et de l'affiliation du signataire
Les propriétés CommonName, Organization, Country et Email couvrent ce que la plupart des workflows d'identité recherchent en premier lieu.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-identity-common.cs
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}");
}
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
La propriété Email vérifie d'abord le DN du sujet pour l'OID emailAddress. Si elle n'est pas présente, le système utilise l'extension rfc822Name du nom alternatif du sujet (SAN). La propriété Country renvoie le code ISO 3166-1 alpha-2 à deux lettres (par exemple, " DE ", " US ", " FR "). Toutes les propriétés de commodité renvoient null si le champ correspondant n'est pas présent dans le certificat.
Lire l'intégralité du DN lorsque vous avez besoin de tout
Pour la journalisation d'audit, l'analyse en aval ou les rapports de conformité, SubjectDN et IssuerDN renvoient les chaînes de nom distinctif complètes.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-identity-full-dn.cs
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}");
}
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
Comment extraire des champs arbitraires de sujet et d'émetteur ?
Les méthodes GetSubjectField(string) et GetIssuerField(string) acceptent soit des noms courts, soit des OID numériques. Ils ne sont pas sensibles à la casse et renvoient null si le champ n'est pas présent.
Noms abrégés pris en charge : CN, O, OU, C, L, ST, E, SERIALNUMBER, SURNAME, T, GIVENNAME, UID, ORGANIZATIONIDENTIFIER.
Lecture de n'importe quel champ de sujet (y compris les OID eIDAS)
Transmettez un nom court tel que "OU" ou un OID numérique tel que "2.5.4.97" (l'identifiant d'organisation eIDAS) pour extraire n'importe quel champ du DN du sujet.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-field-subject.cs
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"}");
}
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
La recherche d'OID numériques est essentielle pour les certificats eIDAS et ceux des secteurs réglementés qui intègrent des identifiants d'organisation, des qualifications professionnelles ou des champs spécifiques à une juridiction non couverts par les noms courts standard.
Lecture des champs de l'émetteur
GetIssuerField fonctionne de la même manière avec le nom distinctif de l'autorité de certification émettrice. Cela est utile pour la validation de la confiance, les rapports des autorités de certification et le regroupement des signatures par autorité émettrice.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-field-issuer.cs
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})");
}
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
Comment vérifier la validité d'un certificat ?
SignerCertificateInfo fournit deux aides à la validation :
IsExpiredrenvoietruesiDateTime.UtcNow > NotAfter.IsValidAt(DateTime)renvoietruesi l'horodatage donné se situe dans la fenêtreNotAfter. L'utilisation typique consiste à vérifier que le certificat était valide au moment de la signature.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-validity.cs
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
if (sig.SigningDate.HasValue)
{
bool validAtSigning = cert.IsValidAt(sig.SigningDate.Value);
Console.WriteLine($"Valid at signing time ({sig.SigningDate.Value}): {validAtSigning}");
}
}
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
If sig.SigningDate.HasValue Then
Dim validAtSigning As Boolean = cert.IsValidAt(sig.SigningDate.Value)
Console.WriteLine($"Valid at signing time ({sig.SigningDate.Value}): {validAtSigning}")
End If
Next
IsExpired renvoie false (et non true) lorsque les dates de validité ne peuvent pas être extraites du certificat. L'assistant est volontairement prudent ; il ne présume pas d'une expiration simplement parce que des métadonnées sont manquantes. Pour les workflows " zero-trust ", traiter explicitement les dates de validité manquantes comme un cas d'échec.Pour les pistes d'audit, consignez à la fois la vérification IsExpired (validité actuelle) et la vérification IsValidAt(signingDate) (validité au moment de la signature). Un certificat qui a depuis expiré pouvait encore être valide au moment de la signature du document ; Ces deux points de données sont importants pour la conformité.
Comment utiliser l'empreinte SHA-256 pour le certificat pinning ?
La propriété Sha256Thumbprint renvoie une chaîne hexadécimale de 64 caractères en majuscules, correspondant au hachage SHA-256 du certificat encodé en DER. Il s'agit de la valeur que vous associez à une liste de certificats de signataires reconnus comme fiables.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-thumbprint-pinning.cs
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}");
}
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
Comment construire un X509Certificate2 à partir de données de certificat brutes ?
La propriété RawData renvoie le certificat encodé en DER sous la forme byte[]. Chaque appel renvoie une copie défensive, de sorte que les données internes ne sont jamais exposées par référence. Vous pouvez l'utiliser pour créer un System.Security.Cryptography.X509Certificates.X509Certificate2 afin d'assurer l'interopérabilité avec les API cryptographiques natives de .NET (construction de chaînes, validation des politiques, vérification des listes de révocation de certificats).
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-x509-interop.cs
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");
}
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
RawData renvoie une nouvelle copie défensive. Le tableau d'octets interne n'est jamais exposé par référence, donc la modification des octets renvoyés n'affectera pas les appels ultérieurs.Ce chemin d'interopérabilité vous permet d'intégrer la vérification de signature d'IronPDF dans des pipelines de validation de certificats .NET existants, tels que X509Chain.Build(), la vérification de révocation via CRL/OCSP ou des implémentations personnalisées de X509CertificateValidator.
Comment parcourir la chaîne de certificats ?
La propriété CertificateChain sur VerifiedSignature renvoie un IReadOnlyList<SignerCertificateInfo> classé par ordre : signataire → autorité(s) de certification intermédiaire(s) → autorité de certification racine. L'index 0 correspond toujours au certificat du signataire (le même objet que SignerCertificate). La liste n'est jamais vide ; Si la chaîne ne peut pas être extraite, elle ne contient que le certificat du signataire.
:path=/static-assets/pdf/content-code-examples/how-to/verify-pdf-signatures-chain-walking.cs
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}");
}
}
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
SignerCertificateInfo de la chaîne expose les mêmes propriétés que SignerCertificate : champs d'identité, validité, empreinte digitale, RawData, GetSubjectField() et GetIssuerField(). Vous pouvez vérifier l'expiration de chaque certificat intermédiaire, comparer l'empreinte digitale de la racine à votre magasin de racines de confiance et consigner la chaîne complète pour les audits de conformité.Prochaines étapes
SignerCertificate et CertificateChain vous offrent une inspection X.509 complète sans quitter l'interface de l'API IronPDF. À partir de là, la suite logique consiste à approfondir les parties d'IronPDF auxquelles ces propriétés s'intègrent.
En ce qui concerne la partie " signature " du flux de travail, le guide pratique sur les signatures numériques couvre la création de certificats, les métadonnées et la signature incrémentielle. Pour la signature basée sur HSM dans des environnements hautement sécurisés, le guide de signature HSM couvre l'intégration PKCS#11. Besoin d'extraits de code prêts à l'emploi ? L'exemple de code sur les signatures numériques les fournit.
Prêt à l'essayer sur vos propres PDF signés ? Commencez votre essai gratuit de 30 jours ou consultez les options de licence.

