該頁面可以包含自動翻譯的文字。

在 C# 和 VB.NET 中驗證 PDF 簽章

PDF 文件中的數位簽章可讓你偵測 PDF 是否遭到竄改。你可以使用 Docotic.Pdf library 來驗證 PDF 檔案中的數位簽章。此函式庫可協助你在 .NET Framework 和 .NET Core 應用程式中讀取簽章屬性。你可以在 下載 C# .NET PDF 程式庫 頁面取得此函式庫與免費的限時授權金鑰。

驗證 PDF 中的數位簽章

在 C# 中驗證 PDF 的數位簽章

Docotic.Pdf library 提供了檢查文件已簽署部分在簽署後是否被變更的方法。你可以檢查簽章是否包含內嵌的 OCSP 和/或 CRL 資料。對任何簽章,都可以檢查其簽署憑證在指定日期是否已被撤銷。

以下 C# 範例示範如何驗證 PDF 簽章,以及檢查簽署憑證的撤銷狀態:

using BitMiracle.Docotic.Pdf;

using var pdf = new PdfDocument("signed.pdf");
Console.WriteLine("Verification result:");

PdfControl? field = pdf.GetControls().FirstOrDefault(c => c.Type == PdfWidgetType.Signature);
if (field is null)
{
    Console.WriteLine("Document does not contain signature fields");
    return;
}

PdfSignature? signature = ((PdfSignatureField)field).Signature;
if (signature is null)
{
    Console.WriteLine("Signature field does not have an associated signature");
    return;
}

PdfSignatureContents contents = signature.Contents;
Console.WriteLine("Signed part is intact: {0}", contents.VerifyDigest());

DateTime signingTime = signature.SigningTime ?? DateTime.MinValue;
Console.WriteLine("Signed on: {0}\n", signingTime.ToShortDateString());

if (contents.CheckHasEmbeddedOcsp())
{
    Console.WriteLine("Signature has OCSP embedded.");
    CheckRevocation(signature, PdfCertificateRevocationCheckMode.EmbeddedOcsp);
}

if (contents.CheckHasEmbeddedCrl())
{
    Console.WriteLine("Signature has CRL embedded.");
    CheckRevocation(signature, PdfCertificateRevocationCheckMode.EmbeddedCrl);
}

CheckRevocation(signature, PdfCertificateRevocationCheckMode.OnlineOcsp);
CheckRevocation(signature, PdfCertificateRevocationCheckMode.OnlineCrl);

var timestampToken = contents.GetTimestampToken();
if (timestampToken != null)
{
    Console.WriteLine("Signature has timestamp embedded.");
    Console.WriteLine("Embedded timestamp: {0}", timestampToken.GenerationTime);

    if (timestampToken.TimestampAuthority != null)
        Console.WriteLine("Timestamp authority: {0}", timestampToken.TimestampAuthority.Name);

    Console.WriteLine("Timestamp is intact: {0}", contents.VerifyTimestamp());
}

private static void CheckRevocation(PdfSignature signature, PdfCertificateRevocationCheckMode mode)
{
    PdfSignatureContents contents = signature.Contents;
    DateTime signingTime = signature.SigningTime ?? DateTime.MinValue;

    foreach (DateTime time in new DateTime[] { signingTime, DateTime.UtcNow })
    {
        bool revoked = contents.CheckIfRevoked(mode, time);
        string status = revoked ? "Revoked" : "Valid";
        string date = time.ToShortDateString();
        Console.WriteLine("Checking using {0} mode: {1} on {2}", mode, status, date);
    }
}

在 GitHub 上,你可以下載並試用完整的 Verify PDF signature C# 和 VB.NET 範例。

在 C# 中讀取 PDF 簽章屬性

Docotic.Pdf 可以讀取簽章屬性,例如簽署者姓名、簽署時間、簽署者聯絡資訊。也可以存取簽章中內嵌的簽署憑證。如果簽章中已內嵌簽發者憑證,函式庫也可以擷取該簽發者憑證。

此範例示範如何在 C# 中讀取簽章及其對應憑證的屬性:

using var pdf = new PdfDocument("signed.pdf");
PdfControl? control = pdf.GetControls().FirstOrDefault(c => c.Type == PdfWidgetType.Signature);
if (control is null)
{
    Console.WriteLine("Document does not contain signature fields");
    return;
}

PdfSignatureField field = (PdfSignatureField)control;
Console.WriteLine("Signature field is invisible: {0}", IsInvisible(field));

PdfSignature? signature = field.Signature;
if (signature is null)
{
    Console.WriteLine("Signature field does not have an associated signature");
    return;
}

Console.WriteLine("Signed by: {0}", signature.Name);
Console.WriteLine("Signing time: {0}", signature.SigningTime);
Console.WriteLine("Signed at: {0}", signature.Location);
Console.WriteLine("Reason for signing: {0}", signature.Reason);
Console.WriteLine("Signer's contact: {0}", signature.ContactInfo);

PdfSignatureContents contents = signature.Contents;
Console.WriteLine("Has OCSP embedded: {0}", contents.CheckHasEmbeddedOcsp());
Console.WriteLine("Has CRL embedded: {0}", contents.CheckHasEmbeddedCrl());

PdfSignatureCertificate certificate = contents.GetSigningCertificate();
Console.WriteLine("== Signing certificate:");
Console.WriteLine("Name: {0}", certificate.Name);
Console.WriteLine("Algorithm: {0}", certificate.AlgorithmName);
Console.WriteLine("Subject DN: {0}", certificate.Subject.Name);
Console.WriteLine("Issuer DN: {0}", certificate.Issuer.Name);
Console.WriteLine("Serial number: {0}", certificate.SerialNumber);
Console.WriteLine("Valid from {0} up to {1}", certificate.ValidFrom, certificate.ValidUpto);
Console.WriteLine("Timestamp Authority URL: {0}", certificate.GetTimestampAuthorityUrl());

PdfSignatureCertificate? issuer = contents.GetIssuerCertificateFor(certificate);
Console.WriteLine("== Issuer certificate:");
if (issuer == null)
{
    Console.WriteLine("The issuer certificate is not embedded");
}
else
{
    Console.WriteLine("Subject DN: {0}", issuer.Subject.Name);
    Console.WriteLine("Issuer DN: {0}", issuer.Issuer.Name);
    Console.WriteLine("Serial number: {0}", issuer.SerialNumber);
}

private static bool IsInvisible(PdfSignatureField field)
{
    return (field.Width == 0 && field.Height == 0) ||
            field.Flags.HasFlag(PdfWidgetFlags.Hidden) ||
            field.Flags.HasFlag(PdfWidgetFlags.NoView);
}

從 GitHub 下載並試用完整的 在 C# 和 VB.NET 中讀取 PDF 簽章屬性 範例。