Diese Seite kann automatisch übersetzten Text enthalten.

PDF-Dokumente mit USB-Token und HSM-Geräten in C# und VB.NET signieren

Vertrauenswürdige Zertifizierungsstellen erlauben das Herunterladen privater Schlüssel für Dokumentsignaturzertifikate nicht mehr. Stattdessen müssen private Schlüssel auf sicherer Hardware wie USB-Token, Smartcards oder Cloud-basierten HSMs gespeichert werden.

Mit der Docotic.Pdf-Bibliothek können Sie PDF-Dokumente in .NET mithilfe von HSM-Geräten signieren. Dieser Artikel beschreibt die Integration mit Azure Key Vault, AWS KMS und PKCS#11-kompatibler Hardware.

Docotic.Pdf-Bibliothek 9.7.18373 Regressionstests 15,244 bestanden NuGet-Downloads insgesamt 5,976,723

Sie erhalten die Bibliothek und einen kostenlosen, zeitlich begrenzten Lizenzschlüssel auf der Seite Laden Sie die C# .NET PDF-Bibliothek herunter.

Externe PDF-Signatur

Voraussetzungen

Die Codebeispiele in diesem Artikel verwenden selbstsignierte Zertifikate zum Signieren von PDF-Dokumenten. PDF-Viewer vertrauen diesen Signaturen standardmäßig nicht. Selbstsignierte Zertifikate sollten nur zu Testzwecken und nicht in Produktionsumgebungen verwendet werden. Verwenden Sie zum Generieren vertrauenswürdiger PDF-Signaturen Dokumentsignaturzertifikate von Zertifizierungsstellen Dritter.

Das richtige Zertifikat verwenden

Bevorzugen Sie Zertifikate von Unternehmen, die in der Adobe Approved Trust List (AATL) aufgeführt sind. Adobe Acrobat vertraut Zertifikaten dieser Unternehmen standardmäßig und meldet die Warnung „Zertifikatgültigkeit unbekannt“ nicht.

Um EU-konforme (eIDAS) Dokumente zu erstellen, benötigen Sie qualifizierte Zertifikate von Anbietern, die in den Vertrauenswürdigen Listen der Europäischen Union (EUTL) aufgeführt sind.

Erfahren Sie, wie Sie Ihr Zertifikat in .NET verwenden

Wenn Sie ein Dokumentensignaturzertifikat bestellen, erhalten Sie in der Regel Zugriff auf ein HSM-Gerät. Dies kann ein physischer USB-Token oder eine Cloud-basierte HSM-Lösung sein.

Anschließend sollten Sie lernen, wie Sie Daten mit diesem HSM signieren. Dies ist in der Regel der schwierigste Teil, da alle Krypto-Anbieter unterschiedlich sind. Beachten Sie die Dokumentation Ihres USB-Tokens oder Ihrer Cloud-API.

Idealerweise benötigen Sie ein entsprechendes .NET SDK. Oder zumindest ein natives SDK, das Sie über Interop in .NET nutzen können.

Ihr Ziel ist es, C#- oder VB.NET-Code zu erhalten, der beliebige Bytes mit Ihrem Zertifikat signieren kann.

PDF-API für externe Signatur

Sobald Sie mit Ihrem HSM-Gerät beliebige Bytes signieren können, können Sie PDF-Dokumente mit Docotic.Pdf signieren. Implementieren Sie dazu die IPdfSigner-Schnittstelle und verwenden Sie sie zum Signieren.

Implementierung der IPdfSigner-Schnittstelle

IPdfSigner deklariert zwei Elemente. Die Eigenschaft SignatureAlgorithm gibt den für die Signatur verwendeten Algorithmus zurück. Typischerweise werden RSA- oder ECDSA-Algorithmen verwendet.

Die Methode Sign ist der zentrale Bestandteil des externen Signaturprozesses. Docotic.Pdf stellt dieser Methode die Byte-Zusammenfassung eines PDF-Dokuments zur Verfügung. Signieren Sie diese Zusammenfassung mit Ihrem HSM-Gerät und geben Sie die Bytes einer digitalen Signatur zurück. Beachten Sie, dass Sie hier kein PKCS#7-Objekt zurückgeben dürfen. Generieren und geben Sie lediglich die kryptografische Signatur zurück.

Docotic.Pdf ruft die Methode Sign zweimal pro Signatur auf. Der erste Aufruf berechnet den für die Signatur benötigten Platz. Der zweite Aufruf dient der eigentlichen Signatur des Dokuments.

Erstellen Sie PdfSigningOptions für externe Signaturen

Verwenden Sie den Konstruktor PdfSigningOptions(IPdfSigner, X509Certificate2[]), um PDF-Dokumente mit Ihrer IPdfSigner-Implementierung zu signieren. Besorgen Sie sich eine Zertifikatskette und geben Sie diese als zweites Argument an. Mindestens ein Zertifikat ist erforderlich, wobei das Signaturzertifikat an erster Stelle stehen sollte.

Das letzte Puzzleteil ist die Eigenschaft PdfSigningOptions.DigestAlgorithm. Der Wert dieser Eigenschaft muss mit IPdfSigner.SignatureAlgorithm und der Implementierung von IPdfSigner.Sign übereinstimmen.

Sehen wir uns an, wie PDF-Dokumente mit externen Signaturen in gängigen Szenarien signiert werden.

PDF-Dokumente mit PKCS#11-Treiber in C# signieren

Wenn Ihr kryptografischer USB-Token oder Ihre Smartcard über einen PKCS#11-Treiber verfügt, können Sie die Bibliotheken Pkcs11Interop.X509Store oder Pkcs11Interop in .NET verwenden. Pkcs11Interop ist kompatibel mit Atos CardOS-Smartcards, YubiKey PIV, SmartCard-HSM, SafeNet ProtectServer HSM und anderen HSMs.

Das Codebeispiel Signieren Sie PDF-Dokumente mit PKCS#11-Treibern zeigt, wie PDF-Dokumente mit einem USB-Token oder einer Smartcard signiert werden. Sie müssen die folgenden Zeilen anpassen:

string pkcsLibraryPath = @"C:\Program Files\SoftHSM2\lib\softhsm2-x64.dll";
ulong slotId = 1743347971;
string alias = "YOUR-ALIAS";
string certLabel = "YOUR-CERTIFICATE";
string pin = "YOUR-PIN";
var digestAlgorithm = PdfDigestAlgorithm.Sha512;

Unsere Beispielkonfiguration verwendet SoftHSM2 als Emulator eines USB-Tokens. In realen Anwendungen benötigen Sie SoftHSM2 nicht. Verwenden Sie stattdessen den mit dem USB-Token gelieferten Treiber.

PDF-Dokumente mit Azure Key Vault signieren

Microsoft Azure Key Vault speichert Zertifikate und Schlüssel sicher. Sie müssen folgende Vorbereitungen treffen:

  1. Erstellen Sie ein Azure-Konto.
  2. Erstellen Sie einen Azure-Benutzer.
  3. Erstellen Sie einen Key Vault.
  4. Erteilen Sie dem ausgewählten Azure-Benutzer Zugriff auf den Key Vault.
  5. Fügen Sie dem Schlüsseltresor ein Signaturzertifikat für Dokumente hinzu. Sie können Zertifikate von integrierten Zertifizierungsstellen importieren.

Verwenden Sie anschließend das NuGet-Paket Azure.Security.KeyVault.Keys für die Anmeldung in .NET. Beispiel-C#-Code für die Signierung mit einem Schlüssel aus Azure Key Vault:

var vaultUrl = new Uri("https://YOUR-VAULT.vault.azure.net/");
var credential = new DefaultAzureCredential();

var keyClient = new KeyClient(vaultUrl, credential);
KeyVaultKey key = keyClient.GetKey("YOUR-KEY");
var cryptoClient = new CryptographyClient(key.Id, credentials);
byte[] messageToSign = ..;
byte[] signature = cryptoClient.SignData(SignatureAlgorithm.RS512, messageToSign).Signature;

Eine entsprechende IPdfSigner-Implementierung könnte folgendermaßen aussehen:

class AzureSigner : IPdfSigner
{
    private readonly CryptographyClient m_client;
    private readonly AzureSignatureAlgorithm m_signingAlgorithm;

    public AzureSigner(CryptographyClient client, AzureSignatureAlgorithm signingAlgorithm)
    {
        m_client = client;
        m_signingAlgorithm = signingAlgorithm;
    }

    public PdfSignatureAlgorithm SignatureAlgorithm
    {
        get
        {
            if (m_signingAlgorithm == AzureSignatureAlgorithm.RS256 ||
                m_signingAlgorithm == AzureSignatureAlgorithm.RS384 ||
                m_signingAlgorithm == AzureSignatureAlgorithm.RS512)
                return PdfSignatureAlgorithm.Rsa;

            throw new NotSupportedException($"Unsupported {nameof(SignatureAlgorithm)} value: {m_signingAlgorithm}");
        }
    }

    public PdfDigestAlgorithm DigestAlgorithm
    {
        get
        {
            if (m_signingAlgorithm == AzureSignatureAlgorithm.RS256)
                return PdfDigestAlgorithm.Sha256;

            if (m_signingAlgorithm == AzureSignatureAlgorithm.RS384)
                return PdfDigestAlgorithm.Sha384;

            if (m_signingAlgorithm == AzureSignatureAlgorithm.RS512)
                return PdfDigestAlgorithm.Sha512;

            throw new NotSupportedException($"Unsupported {nameof(SignatureAlgorithm)} value: {m_signingAlgorithm}");
        }
    }

    public byte[] Sign(byte[] message)
    {
        return m_client.SignData(m_signingAlgorithm, message).Signature;
    }
}

Verwenden Sie abschließend die Klasse AzureSigner, um PDF-Dokumente zu signieren:

CryptographyClient cryptoClient = ..;
using X509Certificate2 cert = ..
var signer = new AzureSigner(cryptoClient, SignatureAlgorithm.RS512);

using var pdf = new PdfDocument();

PdfPage page = pdf.Pages[0];
PdfSignatureField field = page.AddSignatureField(50, 50, 200, 200);

var options = new PdfSigningOptions(signer, new[] { cert })
{
    DigestAlgorithm = signer.DigestAlgorithm,
    Field = field,
};

pdf.SignAndSave(options, ..);

Entdecken Sie das vollständige Codebeispiel Signieren Sie PDF-Dokumente mit Azure Key Vault auf GitHub.

PDF-Dokumente mit AWS KMS signieren

Der AWS Key Management Service (KMS) ist ein weiterer sicherer Speicher für kryptografische Schlüssel. Die Vorbereitung erfolgt analog zu Azure Key Vault:

  1. AWS-Konto erstellen.
  2. IAM-Benutzer erstellen.
  3. Signaturschlüssel hinzufügen.
  4. Zugriff auf die Schlüssel für den ausgewählten IAM-Benutzer gewähren.

Für AWS benötigen Sie das NuGet-Paket AWSSDK.KeyManagementService in .NET. Beispielcode für die PDF-Signierung ähnelt dem Azure-Szenario:

using var pdf = new PdfDocument();

PdfPage page = pdf.Pages[0];
PdfSignatureField field = page.AddSignatureField(50, 50, 200, 200);

var signingAlgorithm = SigningAlgorithmSpec.RSASSA_PSS_SHA_512;
var signer = new AwsSigner("arn:aws:kms:YOUR-id", signingAlgorithm)
var options = new PdfSigningOptions(signer, new[] { cert })
{
    DigestAlgorithm = signer.DigestAlgorithm,
    Field = field,
};

pdf.SignAndSave(options, ..);


class AwsSigner : IPdfSigner
{
    private readonly string m_keyId;
    private readonly SigningAlgorithmSpec m_signingAlgorithm;

    public AwsSigner(string keyId, SigningAlgorithmSpec signingAlgorithm)
    {
        m_keyId = keyId;
        m_signingAlgorithm = signingAlgorithm;
    }

    public PdfSignatureAlgorithm SignatureAlgorithm
    {
        get
        {
            if (m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256 ||
                m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_384 ||
                m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_512)
                return PdfSignatureAlgorithm.Rsa;

            throw new NotSupportedException($"Unsupported {nameof(SigningAlgorithmSpec)} value: {m_signingAlgorithm}");
        }
    }

    public PdfDigestAlgorithm DigestAlgorithm
    {
        get
        {
            string alg = m_signingAlgorithm.Value;
            if (alg.EndsWith("256"))
                return PdfDigestAlgorithm.Sha256;

            if (alg.EndsWith("384"))
                return PdfDigestAlgorithm.Sha384;

            if (alg.EndsWith("512"))
                return PdfDigestAlgorithm.Sha512;

            throw new NotSupportedException($"Unsupported {nameof(SigningAlgorithmSpec)} value: {m_signingAlgorithm}");
        }
    }

    public byte[] Sign(byte[] message)
    {
        using var kmsClient = new AmazonKeyManagementServiceClient();
        using var stream = new MemoryStream(message);
        var signRequest = new SignRequest()
        {
            SigningAlgorithm = m_signingAlgorithm,
            KeyId = m_keyId,
            MessageType = MessageType.RAW,
            Message = stream,
        };
        SignResponse signResponse = kmsClient.SignAsync(signRequest).GetAwaiter().GetResult();
        return signResponse.Signature.ToArray();
    }
}

Das vollständige Codebeispiel Signieren Sie PDF-Dokumente mit AWS KMS ist auch auf GitHub verfügbar.

Abschluss

Nutzen Sie die Docotic.Pdf-Bibliothek, um PDF-Dokumente mit USB-Token, Smartcards oder Cloud-basierten HSMs zu signieren. Implementieren Sie dazu die Schnittstelle IPdfSigner in C#- oder VB.NET-Code.

Laden Sie Codebeispiele für digitale Signaturen in PDF von GitHub herunter und testen Sie sie. Weitere Informationen finden Sie in verwandten Artikeln:

Häufig gestellte Fragen

Wie signiere ich ein PDF mit einem USB-Token oder einer Smartcard?

Verwenden Sie die .NET-Bibliotheken Docotic.Pdf und Pkcs11Interop, um PDF-Dokumente mit Token oder Smartcard zu signieren. Weitere Informationen finden Sie im Abschnitt PDF-Dokumente mit PKCS#11-Treiber in C# signieren.

Wie verwende ich SoftHSM mit meinem USB-Token oder meiner Smartcard?

SoftHSM simuliert ein echtes HSM-Gerät. Sie benötigen SoftHSM nicht, wenn Sie einen USB-Token oder eine Smartcard besitzen. Verwenden Sie stattdessen den mit Ihrem HSM-Gerät gelieferten PKCS#11-Treiber.

Wie signiere ich ein PDF-Dokument mit einer externen Signatur?

Beachten Sie die Abschnitte PDF-Dokumente mit Azure Key Vault signieren und PDF-Dokumente mit AWS KMS signieren. Die externe PDF-Signierung mit anderen Cloud-basierten HSMs erfolgt nach einem ähnlichen Verfahren.

Wie verwende ich Azure Key Vault in .NET?

Verwenden Sie das NuGet-Paket Azure.Security.KeyVault.Keys. Probieren Sie das Codebeispiel Signieren Sie PDF-Dokumente mit Azure Key Vault von GitHub aus.