sgcSign in fünf Minuten

Zwei Komponenten signieren ein Dokument: ein Signierer und ein Schlüsselanbieter. Diese Seite signiert ein PDF mit PAdES, mit einem Zertifikat aus dem Windows-Zertifikatspeicher, und zeigt dann, wie du das Ergebnis verifizierst. Wenn du lieber XML signieren möchtest, gibt es unten verlinkt eine ausführlichere XAdES-Anleitung.

PAdES, XAdES, CAdES, ASiC
Zehn Schlüsselanbieter, von PFX bis Cloud-HSM
Windows, Win32 und Win64

Ein Signierer und ein Schlüsselanbieter

Der Signierer kennt das Dokumentformat. Der Schlüsselanbieter weiß, wo der private Schlüssel liegt. Beide treffen sich in einer Eigenschaft.

Der Signierer

TsgcPAdESSigner, deklariert in sgcSign_PAdES.pas und auf der Palettenseite SGC Sign registriert. SignPDFFile nimmt einen Eingabepfad und einen Ausgabepfad entgegen.

Der Schlüsselanbieter

TsgcWindowsCertStoreProvider für den Windows-Zertifikatspeicher oder TsgcPFXKeyProvider für eine .pfx-Datei. Beide sind auf derselben Palettenseite.

Die Eigenschaft, die beide verbindet

KeyProvider, deren Typ das Interface IsgcKeyProvider ist und keine Komponentenreferenz. Dieser Unterschied ist für die Lebensdauer wichtig, und der Abschnitt zu den Stolperfallen unten erklärt, warum.

Plattform

Win32, Win64, Linux64, macOS auf Intel und Apple Silicon, iOS und Android. Unter Windows laufen Hashing und Signieren über die Windows-CNG-API, auf allen anderen Plattformen über die eigene reine Pascal-Kryptografie der Bibliothek, ohne OpenSSL auszuliefern. Der Provider für den Windows-Zertifikatspeicher ist die eine Komponente, die auf Windows beschränkt bleibt.

Voraussetzungen und Editionen

sgcSign hat keine Funktionsstufen, daher geht es in dieser Tabelle um Compiler und Plattformen und nicht um Editionen.

Was Wert
IDE Delphi 7 bis RAD Studio 13 sowie C++Builder. Beim C++Builder-Weg kommt der lib-Ordner in den System-Include-Pfad statt in den Bibliothekspfad.
Uses-Klausel Die Demo schreibt sgcSign_Types, sgcSign_Interfaces, sgcSign_Classes, sgcSign_PAdES, sgcSign_KeyProvider_WinCertStore, sgcSign_KeyProvider_PEM, sgcSign_KeyProvider_PFX. Lass die Provider weg, die du nicht verwendest.
Editionen Es gibt keine. Die sgcVer.inc des Produkts enthält überhaupt kein SGC_EDT_*-Define, und keine Funktion wird nach Stufe gesteuert. Eine Bibliothek, jede Komponente, in jeder Lizenz. Die kommerziellen Stufen richten sich nach der Anzahl der Arbeitsplätze: Single, Team und Site, dazu eine kostenlose Community Edition.
Plattform, im Quelltext geprüft Win32, Win64, Linux64, OSX64, OSXARM64, iOS und Android. Die Kryptografie läuft über eine einzige Seam-Unit, sgcSign_Crypto.pas, die unter Windows CNG und überall sonst reines Pascal ist. HTTP ist unter Windows WinHTTP und sonst der Delphi-RTL-Client, und die Laufzeitpakete aktivieren Linux64 und macOS auf Intel ab Delphi 10.3, Android und iOS ab 10.4 sowie macOS auf Apple Silicon ab 11. sgcSign_KeyProvider_WinCertStore.pas ist die eine Unit, die nur unter Windows läuft.
Externe Abhängigkeiten Keine. Unter Windows ruft die Bibliothek die Windows-APIs CNG und WinHTTP direkt auf, und auf den anderen Plattformen verwendet sie ihre eigene reine Pascal-Kryptografie und den HTTP-Client der Delphi-RTL, sodass keine OpenSSL-DLLs mit deiner Anwendung ausgeliefert werden müssen.
Standardwerte Ein frischer TsgcPAdESSigner hat bereits ein brauchbares Profil: Der Konstruktor setzt das einfache PAdES-Profil, die Signaturstufe Baseline B und SHA-256. Du musst Profile nicht anfassen, um eine gültige Signatur zu erzeugen.

Du bevorzugst XML statt PDF? Die Fünf-Minuten-XAdES-Anleitung signiert stattdessen ein XML-Dokument mit einer PFX-Datei und behandelt die Unicode-Stolperfalle von Delphi 7 und die UTC-Signaturzeit. Diese Seite ist das Gegenstück für PDF und Zertifikatspeicher.

Installieren und die Palettenseite finden

Kompiliere das Laufzeitpaket, bevor du das Entwurfszeitpaket installierst, denn Letzteres verweist auf Ersteres.

1. Entpacken

Entpacke den Download in einen Ordner, unten {$DIR} genannt.

2. Bibliothekspfad

Tools, Umgebungsoptionen, Verzeichnisse. Füge {$DIR}\delphi\source hinzu, was für jede RAD-Studio-Version gilt.

3. Den lib-Ordner hinzufügen

Füge außerdem den versionsspezifischen Ordner hinzu, zum Beispiel {$DIR}\delphi\libD13\$(Platform) bei RAD Studio 13, bis hinunter zu libD7 bei Delphi 7. Bei C++Builder kommen sie stattdessen in den System-Include-Pfad.

4. Pakete erstellen

Öffne Packages\sgcSignD13.groupproj für deine IDE-Version oder sgcSignC13.groupproj für C++Builder. Kompiliere zuerst das Paket sgcSign und installiere dann dclsgcSign.

5. Palette prüfen

Es erscheint eine Seite namens SGC Sign mit den Signierern, dem Verifizierer, den Zeitstempel- und OCSP-Clients und den zehn Schlüsselanbietern. Unter Windows enthält sie außerdem den Authenticode-Signierer und -Verifizierer.

Ein PDF signieren, in etwa zwanzig Zeilen

Wähle ein Zertifikat, erzeuge den Signierer, richte ihn auf den Anbieter und rufe SignPDFFile auf. Der erste Tab verwendet den Windows-Zertifikatspeicher, der zweite eine PFX-Datei.

frmMain.pas
uses
  SysUtils, Classes,
  // sgcSign
  sgcSign_Types, sgcSign_Interfaces, sgcSign_Classes,
  sgcSign_PAdES, sgcSign_KeyProvider_WinCertStore;

procedure TFormMain.btnSignClick(Sender: TObject);
var
  vSigner: TsgcPAdESSigner;
  vKeyProvider: TsgcWindowsCertStoreProvider;
  vProviderIntf: IsgcKeyProvider;
  vOutputFile: string;
begin
  vKeyProvider := TsgcWindowsCertStoreProvider.Create(nil);
  vSigner := TsgcPAdESSigner.Create(nil);
  try
    vKeyProvider.SelectCertificateBySubject('My Company');
    Log('Certificate found: ' + vKeyProvider.Certificate.Subject);

    // Hold the interface in an explicit local: an inline "as" cast
    // would leave a compiler-generated interface temporary alive in
    // this stack frame until the routine returns, i.e. past
    // vKeyProvider.Free, and releasing it would touch freed memory.
    vProviderIntf := vKeyProvider as IsgcKeyProvider;
    vSigner.KeyProvider := vProviderIntf;
    vSigner.Reason := 'Demo signature';
    vSigner.Location := 'Spain';
    vSigner.SignerName := 'sgcSign Demo';

    vOutputFile := ChangeFileExt(edInputFile.Text, '_signed.pdf');
    vSigner.SignPDFFile(edInputFile.Text, vOutputFile);

    Log('SUCCESS: PDF signed with PAdES profile');
    Log('Output file: ' + vOutputFile);
  finally
    vSigner.Free;
    vProviderIntf := nil;
    vKeyProvider.Free;
  end;
end;

Beachte, was hier nicht steht. Profile wird nie angefasst, weil der Konstruktor bereits ein einfaches PAdES-Profil, die Signaturstufe Baseline B und SHA-256 setzt. Der Kommentar zum Interface-Temporary stammt aus der mitgelieferten Demo, und die Freigabereihenfolge im finally-Block ist der Grund, warum er wichtig ist.

frmMain.pas
uses
  SysUtils, Classes,
  // sgcSign
  sgcSign_Types, sgcSign_Interfaces, sgcSign_Classes,
  sgcSign_PAdES, sgcSign_KeyProvider_PFX;

var
  vSigner: TsgcPAdESSigner;
  vKeyProvider: TsgcPFXKeyProvider;
  vProviderIntf: IsgcKeyProvider;
begin
  vKeyProvider := TsgcPFXKeyProvider.Create(nil);
  vSigner := TsgcPAdESSigner.Create(nil);
  try
    vKeyProvider.FileName := 'C:\certs\signer.pfx';
    vKeyProvider.Password := GetPfxPassword;
    vKeyProvider.LoadFromFile;
    Log('Certificate loaded (PFX): ' + vKeyProvider.Certificate.Subject);

    vProviderIntf := vKeyProvider as IsgcKeyProvider;
    vSigner.KeyProvider := vProviderIntf;

    vSigner.SignPDFFile('C:\docs\contract.pdf',
      'C:\docs\contract_signed.pdf');
  finally
    vSigner.Free;
    vProviderIntf := nil;
    vKeyProvider.Free;
  end;
end;

Der einzige Unterschied zum ersten Tab ist, welchen Anbieter du erzeugst und wie du ihn auf einen Schlüssel richtest. Alles ab KeyProvider := ist identisch, und das gilt für alle zehn Anbieter, einschließlich PKCS#11-Hardware und der Cloud-Schlüsseldienste.

uVerify.pas
uses
  SysUtils, Classes,
  // sgcSign
  sgcSign_Types, sgcSign_Interfaces, sgcSign_Verifier;

var
  oVerifier: TsgcSignatureVerifier;
  vVerifier: IsgcSignatureVerifier;
  oStream: TFileStream;
begin
  oVerifier := TsgcSignatureVerifier.Create(nil);
  oStream := TFileStream.Create('C:\docs\contract_signed.pdf',
    fmOpenRead or fmShareDenyWrite);
  try
    // VerifyPDF is reached through the interface the component implements
    vVerifier := oVerifier as IsgcSignatureVerifier;

    if vVerifier.VerifyPDF(oStream) = vsValid then
      Writeln('valid')
    else
      Writeln(oVerifier.GetVerificationDetails);
  finally
    vVerifier := nil;
    oStream.Free;
    oVerifier.Free;
  end;
end;

Dieselbe Interface-Regel wie beim Signierer: Weise den Cast einer benannten lokalen Variable zu und leere sie, bevor du die Komponente freigibst. GetValidationReportXML erzeugt einen Bericht im ETSI-Validierungsberichtsformat, wenn ein Boolean als Nachweis nicht genügt.

Die ersten beiden Tabs stammen aus der mitgelieferten Demo Demos\Delphi\PAdES\frmMain.pas, wobei ihre Verzweigungen pro Tab auf einen Pfad reduziert wurden. Der Kommentar dazu, das Interface in einer benannten lokalen Variable zu halten, stammt aus der Demo und ist es wert, beibehalten zu werden. Eine umfangreichere Schwester-Demo, Demos\Delphi\PAdES_Providers, tut dasselbe mit Hardware- und Cloud-Anbietern.

Die Signatur prüfen, nicht nur die Datei ansehen

Eine Datei ist entstanden. Das ist nicht dasselbe wie eine Signatur, die validiert.

Das Zertifikat wurde aufgelöst

Lies nach der Auswahl Certificate.Subject, wie es die Demo tut. Das ist der Unterschied zwischen dem Signieren mit dem gemeinten Zertifikat und dem mit dem, das zuerst passte. IsLoaded beantwortet dieselbe Frage als Boolean.

Die Datei ist entstanden

SignPDFFile schreibt den Ausgabepfad, den du angegeben hast. Die mitgelieferte Demo leitet ihn mit ChangeFileExt ab, sodass die signierte Datei neben dem Original landet.

Es löst eine Exception aus, es gibt keinen Code zurück

Es gibt kein Ergebnis zu testen, setze den Aufruf also in ein try except und lies die Exception-Meldung. Das tut die Demo, und es ist der einzige Fehlerkanal.

Die Signatur validiert

Eine Datei ist keine gültige Signatur. TsgcSignatureVerifier.VerifyPDF liefert einen TsgcVerificationStatus, den du mit vsValid vergleichst, und GetVerificationDetails erklärt einen Fehler. Die Datei in einem PDF-Reader zu öffnen, zeigt einem Menschen dasselbe.

Was beim ersten Mal meistens schiefgeht

Sechs Probleme erklären fast jede erste Signatur.

Eine Zugriffsverletzung beim Beenden

Davor warnt die Demo in ihrem eigenen Kommentar. KeyProvider nimmt ein IsgcKeyProvider entgegen, ein Inline-Cast mit as lässt also eine vom Compiler erzeugte Interface-Referenz bis zum Ende der Routine am Leben, also nachdem du die Provider-Komponente freigegeben hast. Weise das Interface einer benannten lokalen Variable zu und gib in dieser Reihenfolge frei: Signierer, dann Interface auf nil, dann Anbieter.

Profile ist kein String

Es ist ein TsgcSignProfileConfig-Objekt. Du setzt Profile.Profile und Profile.SignatureLevel, nicht Profile := 'something'. Der Konstruktor füllt bereits einen brauchbaren Standardwert ein, das erste Beispiel muss es also gar nicht anfassen.

Es wird kein Zertifikat gefunden

SelectCertificateBySubject sucht anhand des Subjects und SelectCertificateByThumbprint anhand des Fingerabdrucks. Lies nach der Auswahl Certificate.Subject, wie es die Demo tut, damit du siehst, welches Zertifikat du tatsächlich bekommen hast. EnumerateCertificates listet auf, was verfügbar ist.

Es lässt sich außerhalb von Windows nicht kompilieren

Es kann es nicht. Der Signierer und jeder Anbieter tragen Windows ohne Bedingung in die Interface-Uses-Klausel ein, das ist also ein Compilerfehler und keine leere Unit. sgcSign ist eine Windows-Bibliothek.

Die Signatur erscheint im Reader als unbekannt

Eine einfache Signatur enthält weder einen Vertrauensanker noch Sperrdaten. Füge über TSAClient einen Zeitstempel hinzu und wechsle zu einem Langzeitprofil, wenn das Dokument auch nach Ablauf des Zertifikats prüfbar bleiben muss.

SignPDFFile löst eine Exception aus, statt einen Code zurückzugeben

Das ist das Design. Es gibt keinen Rückgabewert zu testen, setze den Aufruf also in ein try except und lies die Exception-Meldung, was die mitgelieferte Demo tut.

Über die erste Signatur hinaus

Vier Richtungen, alle in derselben Bibliothek.

Andere Dokumentformate

XAdES und XMLDSig für XML, CAdES für abgetrenntes CMS, ASiC-Container sowie eigene Signierer für ClickOnce-, NuGet- und VSIX-Pakete. Unter Windows gibt es zusätzlich einen Authenticode-Signierer.

Alle sgcSign-Komponenten

Wo der Schlüssel liegt

Zehn Schlüsselanbieter liegen bei: PFX, PEM, der Windows-Speicher, PKCS#11-Hardware, Azure Trusted Signing, AWS KMS, Google Cloud KMS, Certum SimplySign, HashiCorp Vault und das CSC-Protokoll für Remote-Signierung.

Schlüsselanbieter

Länderprofile

Einundzwanzig Länder- und Branchenprofile, vom spanischen VeriFactu bis zu den EU-Rechnungsformaten, jeweils mit den Feldern und der Signaturstufe, die dieses Regime erwartet.

Signaturprofile

Woanders signieren

sgcSign Server ist ein selbst gehosteter Daemon, der die Schlüssel hält und auf Anfrage signiert, sodass das Zertifikat nie den Rechner verlässt, dem du es anvertraust.

sgcSign Server

Referenz, Demos und Dokumentation

Die Demo-Projekte liegen im Download unter Demos\Delphi. Die PAdES-Demo ist die, aus der diese Seite gebaut ist.

Fünf-Minuten-XAdES-Anleitung Der ausführliche Schnellstart: ein frisches VCL-Projekt, eine PFX-Datei und ein signierter XML-Umschlag.
Schlüsselanbieter Alle zehn Orte, an denen ein privater Schlüssel liegen kann, und was jeder braucht.
Signaturprofile Die einundzwanzig Länder- und Branchenprofile und was jedes verlangt.
Tutorial zum PDF-Signieren Eine ausführlichere Anleitung zu PAdES, einschließlich sichtbarer Signaturen.
sgcSign Server Der selbst gehostete Signatur-Daemon, wenn der Schlüssel nicht wandern darf.
Testversion herunterladen Derselbe Installer wie in der Vollversion, zeitlich begrenzt, dazu eine kostenlose Community Edition.

Zum Weiterlesen: die Einführung in sgcSign und der Code-Signing-Server. Jedes Produkt hat einen eigenen Schnellstart, aufgelistet auf der Seite Erste Schritte.

Fragen zum sgcSign-Schnellstart

TsgcPAdESSigner, deklariert in sgcSign_PAdES.pas, und ein Schlüsselanbieter. Für den Windows-Zertifikatspeicher ist das TsgcWindowsCertStoreProvider aus sgcSign_KeyProvider_WinCertStore.pas. Für eine .pfx-Datei ist es TsgcPFXKeyProvider aus sgcSign_KeyProvider_PFX.pas. Beide liegen auf der Palettenseite SGC Sign. Weise den Anbieter der Eigenschaft KeyProvider des Signierers zu und rufe dann SignPDFFile(aInputFile, aOutputFile) auf.
Weil KeyProvider als Interface IsgcKeyProvider typisiert ist und nicht als Komponente. Ein Inline-Cast mit as erzeugt ein vom Compiler erzeugtes Interface-Temporary, das im Stack-Frame bis zum Ende der Routine am Leben bleibt, also nachdem die Provider-Komponente freigegeben wurde, und seine Freigabe berührt dann Speicher, der nicht mehr existiert. Die Demo weist den Cast einer benannten lokalen Variable zu und gibt dann in der Reihenfolge Signierer, Interface auf nil, Anbieter frei. Übernimm diese Reihenfolge.
Es gibt keine Editionen. Die sgcVer.inc des Produkts enthält überhaupt kein SGC_EDT_*-Define, und keine Komponente und kein Format wird nach Stufe gesteuert. Jede Lizenz enthält jeden Signierer, jeden Schlüsselanbieter und jedes Länderprofil. Die kommerziellen Stufen sind Arbeitsplatzzahlen, Single, Team und Site, und neben der Testversion gibt es eine kostenlose Community Edition.
Ja, seit 2026.10.0. Die Bibliothek baut und läuft unter Linux64, unter macOS für Intel und Apple Silicon, unter iOS und Android sowie unter Win32 und Win64. Dokumente signieren und verifizieren, PKCS#12-Dateien lesen und schreiben, PE-Dateien, Kataloge, MSI, MSP, MSIX und APPX signieren und PKCS#11-Token funktionieren dort alle, und der Signaturserver läuft unter Linux als systemd-Daemon. Zwei Anbieter nutzen den Schlüsselspeicher, den die Plattform bereits hat, die Apple-Keychain und den Android KeyStore. Zwei Dinge bleiben bei Windows: der Provider für den Windows-Zertifikatspeicher und die Windows-spezifischen Formate im Server und im Kommandozeilenwerkzeug, die in einem Nicht-Windows-Build noch abgelehnt werden, obwohl die Bibliothek selbst sie signiert.
Nicht für eine erste Signatur. Der Konstruktor setzt bereits ein einfaches PAdES-Profil, die Signaturstufe Baseline B und SHA-256. Wenn du es ändern willst, ist Profile ein TsgcSignProfileConfig-Objekt, du setzt also Profile.Profile und Profile.SignatureLevel, statt einen String zuzuweisen. Für eine Langzeitsignatur wechselst du zum LTV-Profil und zur Baseline-Stufe LT und hängst einen TSAClient an.
Verwende TsgcSignatureVerifier. VerifyPDF nimmt einen Stream entgegen und liefert einen TsgcVerificationStatus, den du mit vsValid vergleichst. GetVerificationDetails erklärt einen Fehler, und GetValidationReportXML erzeugt einen Bericht im ETSI-Validierungsberichtsformat, wenn du einen Nachweis statt eines Booleans brauchst.
Nein. Unter Windows hasht und signiert sgcSign über die APIs CNG und BCrypt und spricht über WinHTTP mit dem Netzwerk. Unter Linux, macOS, iOS und Android verwendet es seine eigene reine Pascal-Kryptografie und den HTTP-Client der Delphi-RTL. In beiden Fällen gibt es keine OpenSSL-DLLs auszuliefern, was einer der Gründe ist, warum die Bereitstellung einfach ist.
Sie decken absichtlich unterschiedliche Aufgaben ab. Der Fünf-Minuten-Schnellstart baut ein frisches VCL-Projekt, verwendet eine PFX-Datei und signiert ein XML-Dokument mit XAdES, und er geht auf die Unicode-Stolperfalle von Delphi 7 und die UTC-Signaturzeit ein. Diese Seite signiert ein PDF mit PAdES mit einem Zertifikat aus dem Windows-Speicher, so wie es die mitgelieferte PAdES-Demo tut. Lies zuerst diese und dann jene, wenn du XML brauchst.
Bestes Preis-Leistungs-Verhältnis: All-AccessAlle eSeGeCe-Produkte, inklusive Premium-Support, ab €1,059 pro Jahr.
All-Access-Preise ansehen

Bereit, dein erstes Dokument zu signieren?

Lade die Testversion herunter oder starte mit der kostenlosen Community Edition.