Diese Anleitung zeigt, wie Sie eine Rechnung mit der Cloud Signature Consortium v2 API auf CodeB Sovereign Communications signieren, mit einem qualifizierten Zeitstempel nach RFC 3161 versehen und OCSP-Revocation-Daten für die langfristige Validierung (PAdES-B-LT) einbetten. Ergebnis: eine PDF, die die GoBD-Anforderung an Unveränderbarkeit kryptographisch erfüllt.
Voraussetzungen. Sie benötigen (1) einen OIDC-Bearer-Access-Token für Ihren CodeB-Tenant, (2) HTTPS-Zugriff auf https://<tenant>/csc.ashx, (3) eine PDF-Datei, deren Byte-Range Sie hashen wollen. Für ein produktives Rechnungsarchiv brauchen Sie zusätzlich einen konfigurierten QTSP als Zeitstempel-Quelle (Standard: Sectigo).
1 OIDC-Bearer-Access-Token beziehen
Der CSC v2 Endpunkt authentifiziert Aufrufer per OIDC-Bearer. Zwei Wege sind üblich:
Interaktiv (authorization_code) — für Web-Applikationen mit angemeldetem Nutzer.
Client-Credentials — für Server-zu-Server-Signieren aus Buchhaltungssoftware.
Client-Credentials-Beispiel (Ihr Tenant muss den Grant aktiviert haben):
Die Antwort enthält access_token, das im weiteren Ablauf als Authorization: Bearer <token> mitgeschickt wird.
Hinweis zur Aussagekraft: der acting sub im Token bestimmt die Signaturidentität — das Zertifikat wird beim ersten Zugriff aus dem OIDC-Profil mit Vor-, Nachnamen und E-Mail befüllt.
2 Signaturzertifikat abfragen
Erste Abfrage listet die verfügbaren Credentials des Nutzers auf:
Antwort enthält cert.certificates[] (PEM), key.algo (1.2.840.10045.4.3.2 = ECDSA-SHA256) und SCAL (1 für automatische Autorisierung, 2 für 2FA-Bestätigung).
3 SHA-256-Hash der Rechnung bilden
Der Endpunkt signiert einen SHA-256-Hash, nicht die PDF selbst. Bei PAdES ist der Hash der ByteRange-Bereich der zu signierenden PDF — also alles außer dem Platzhalter, wo die Signatur eingesetzt wird.
Für schnelle Tests reicht auch der Hash über die gesamte Datei — dann liefert Ihnen die API zwar eine gültige Signatur, aber die Rechnung ist keine PAdES-konforme PDF-Signatur; nutzen Sie signatures/signDoc stattdessen, wenn der Server die PDF-Einhüllung übernehmen soll.
4 Signaturautorisierung (SAD) beziehen
CSC v2 trennt Autorisierung von Signaturausführung. Der Autorisierungsschritt liefert ein kurzlebiges SAD-JWT, das die Signatur eines konkreten Hashes durch den zugehörigen Nutzer freischaltet:
Antwort: {"SAD": "eyJ..."}. Das SAD ist ein JWT mit den claims sub, credential_id, hash, exp. Gültigkeit typisch 5 Minuten.
SCAL2-Konten (2FA erforderlich): Bei SCAL2-Konten liefert dieser Endpunkt stattdessen eine authorization_id, und Sie müssen den zweiten Faktor über credentials/authorize/confirm bestätigen. Details siehe API-Referenz.
5 Hash signieren
Mit SAD und Hash wird jetzt die eigentliche Signatur angefordert:
Antwort: {"signatures": ["MEUCIQ..."]} — die CMS-Signaturbytes, base64-kodiert, die in das /Sig-Dictionary der PDF eingesetzt werden.
Vereinfachung: signDoc statt signHash
Wenn Ihr Client die PDF-Byte-Range nicht selbst konstruieren will, lädt signatures/signDoc die komplette PDF hoch und liefert die fertig signierte PDF zurück. Praktisch für kleine Volumen; skaliert schlechter, weil jede PDF komplett über die Leitung geht.
Damit die Signatur beweiskräftig auf einen amtlich beglaubigten Zeitpunkt gebunden ist, wird ein qualifizierter Zeitstempel angehängt. CodeB proxiert die QTSP-Verbindung:
Die zurückgegebene timestamp-token.tst ist der RFC-3161-Zeitstempel-Token, den Sie als id-aa-signatureTimeStampToken-Attribut in die CMS-Signatur einbetten. Das Ergebnis ist eine PAdES-B-T-Signatur.
Standard-QTSP ist Sectigo (URL http://timestamp.sectigo.com/qualified). Die Konfiguration liegt im Windows-Registry-Wert HKLM\SOFTWARE\CodeB\TSAURL. Kunden mit eigener QTSP-Beziehung (z.B. maltesische Gattaca) können den Endpunkt umkonfigurieren.
7 OCSP-Revocation-Daten einbetten (PAdES-B-LT)
Damit die Signatur auch nach zehn Jahren noch verifizierbar bleibt, müssen die zum Signaturzeitpunkt gültigen Revocation-Daten des Signaturzertifikats in die PDF eingebettet werden. Ohne diesen Schritt müsste ein späterer Verifikationstool den ursprünglichen OCSP-Responder erreichen — der möglicherweise nicht mehr existiert.
Antwort: {"ocsp_response": "MIIBoAoBAK..."}. Die OCSP-Antwort wird als id-aa-ets-revocationValues-Attribut in die CMS-Signatur eingebettet. Das Ergebnis ist eine PAdES-B-LT-Signatur — das empfohlene Niveau für Rechnungsarchive mit zehnjähriger Aufbewahrungsfrist.
8 Fehlerbehandlung
Der Endpunkt liefert bei Fehlern strukturierte JSON-Antworten nach RFC 6749 Muster:
{
"error": "invalid_request",
"error_description": "hash: must be 32 raw bytes (SHA-256), base64-encoded"
}
Häufige Fehler und deren Ursache:
400 invalid_request — fehlende oder falsche Parameter. Meist ist der Hash nicht 32 Byte lang oder nicht base64-kodiert.
400 only_sha256_supported — ein anderer Hash-Algorithmus als SHA-256 wurde angefordert.
401 invalid_token — Bearer-Token abgelaufen oder ungültig. Neu holen.
403 https_required — der Aufruf kam über HTTP. CSC v2 akzeptiert nur HTTPS.
413 body_too_large — Body über 32 KiB (bzw. 10 MiB für signDoc). PDF vor dem Hochladen kompaktieren oder signHash nutzen.
429 — Rate-Limit überschritten (30 Anfragen/min pro Aktion und IP). Antwort enthält Retry-After: 30.
501 crypto_module_not_configured — das Signaturmodul ist auf dem Tenant nicht konfiguriert. IT-Administrator kontaktieren.