Öffentliche API · Cloud Signature Consortium v2 · Tier C1-Subset
/csc/v2 · Fern-Signaturdienst.
Ein Cloud-Signature-Consortium-(CSC)-API-v2-Tier-C1-Subset auf CodeB Sovereign Communications. Jeder authentifizierte Nutzer erhält ein EC-P-256-Signaturzertifikat, dessen Subject Distinguished Name aus dem OIDC-Profil angereichert wird (CN = vollständiger Name, Vorname / Nachname / E-Mail mit SAN rfc822Name). Signierte Hashes kommen als RFC-5652-CMS zurück; serverseitiges signDoc baut die vollständige PAdES-B-B-/-B-T-Hülle zusammen; ein RFC-3161-TSA-Proxy unter signatures/timestamp hebt eine client-seitig gebaute Signatur auf PAdES-B-T an.
Umfangserklärung — ausschließlich fortgeschrittene elektronische Signatur.
Dieser Fern-Signaturdienst erzeugt AdES gemäß Verordnung (EU) 910/2014 Artikel 3(11). Der Signaturschlüssel ist software-basiert (pro Tenant PFX; pro Nutzer in Phase 1b) und das Zertifikat ist selbstsigniert durch eine tenant-interne CA — es ist keine qualifizierte Signaturerstellungseinheit (QSCD) und keine qualifizierte elektronische Signatur (QES). Die ICryptoModule-Abstraktion ist HSM-vorbereitet (Azure Key Vault und PKCS#11 sind gestubbt und liefern HTTP 501, bis sie verkabelt sind). Bereit für Integrationen mit der European Digital Identity Wallet über die OIDC + OID4VP-Basis.
Zwei URL-Formen, ein Handler. Endpunkte werden über ?action=<Pfad> dispatched. Jede unten gezeigte Form POST /csc/v2/<Segment> wird von IIS zu POST /csc.ashx?action=<Segment> umgeschrieben. Beide Formen werden akzeptiert. Die Präfix-Form ist die, die /csc/v2/info bewirbt und die spec-konforme CSC-Clients erwarten.
Auth. Außer info (offen) und auth/login (das lediglich einen bereits validierten Bearer widerspiegelt) erfordert jeder Endpunkt einen OIDC-Access-Token im Header Authorization: Bearer <Token>. Der Bearer wird gegen /oidc.ashx?action=introspect introspected, um den handelnden sub zu ermitteln; dieser Wert schlüsselt das Pro-Nutzer-Zertifikat und erscheint als sub-Claim in jedem SAD-JWT.
Gemeinsame Limits (Host-Level RASP). Körper sind auf 32 KiB begrenzt (10 MiB für signatures/signDoc). Ein Pro-IP-Rate-Bucket lässt 30 Requests pro Minute pro Aktion zu; Überschreiten liefert 429 mit Retry-After: 30. Nicht-HTTPS-Anfragen werden mit 403 (https_required) abgelehnt. Alle Hashes MÜSSEN SHA-256 sein (32 Roh-Bytes, base64-kodiert); andere Digests liefern 400 only_sha256_supported.
CSC v2 §11.1 Servicemetadaten. Liefert unterstützte Spec-Version, Methodenliste, Signaturalgorithmus-OIDs und den Authentifizierungstyp. Auch per GET erreichbar für Smoke-Tests.
1.2.840.10045.4.3.2 = ecdsa-with-SHA256; 1.2.840.113549.1.1.11 = sha256WithRSAEncryption. eu_eidas_aes ist CSC-Bezeichner für AdES und deckt sich mit der obigen Umfangserklärung.
Session-Level-Tokenaustausch. Akzeptiert den OIDC-Access-Token im Authorization-Header, introspected ihn gegen den CodeB-OIDC-Provider und spiegelt ihn mit fester expires_in zurück.
Widerruft einen zuvor ausgestellten Session-Token. Delegiert an /oidc.ashx?action=revoke. Antwortet immer mit { ok: true }, damit Revoke keine Informationen über vorherige Token-Gültigkeit leakt.
Listet die CSC-credentialIDs des authentifizierten Nutzers. Ab Phase 1b hat jeder Nutzer genau ein Pro-Nutzer-EC-P-256-Credential. Bei Csc:PerUserCerts=false teilen sich alle Nutzer das tenantweite Fallback-Credential.
Liefert die Deskriptor-Metadaten eines spezifischen Credentials: Leaf-Zertifikat (base64 DER), Subject DN, Issuer DN, Seriennummer, Gültigkeitsfenster, Schlüssel-Algorithmus-OID + Schlüssellänge + Kurven-OID sowie Modul-Attribute (identisch zu CSC v2 §11.4 mit CodeB-eigenem moduleType und moduleCertification aus der ICryptoModule-Abstraktion).
Erwirbt Signature-Activation-Data (SAD) — ein kurzlebiges JWT, gebunden an die spezifische Hash-Liste, die der Aufrufer signieren möchte. Bei SCAL1 wird die SAD sofort zurückgegeben; bei SCAL2 wird ein pending-Datensatz angelegt und der Aufrufer muss den Zweitfaktor über credentials/authorize/confirm vervollständigen. Auswahl zwischen SCAL1 und SCAL2 über Tenant-Standard (Csc:DefaultScal) oder per-Request-Override ?scal=1|2.
SAD ist ein kompaktes JWS mit Claims iss, sub (= introspected Bearer subject), aud=csc-sad, iat, exp (iat + 300 s), jti, credentialID, hash, hashAlgo, numSignatures, scal=1. Signiert mit ES256 (RS256 als Fallback bei RSA-Credential).
SCAL2-Zweitfaktor-Bestätigung. Der Client postet entweder eine WebAuthn-Assertion (verifiziert über CodeB.Passkeys.AuthenticationFacade nach WebAuthn Level 2) oder eine PIN entweder im JSON-Körper oder im Header X-CSC-Sign-PIN (4–12 Hex-/Dezimal-Zeichen).
Signiert einen oder mehrere vorberechnete SHA-256-Hashes. Der Aufrufer baut die CMS-Hülle client-seitig (wie sign.html für PAdES-B-B/-B-T). Die SAD muss exakt an die hier übergebene Hash-Liste gebunden sein — Anzahl und Inhalt werden constant-time verifiziert.
CSC v2 §11.10 — serverseitige Ganzdokument-Signatur. Der Aufrufer schickt eines oder mehrere rohe PDFs (base64) und CodeB führt inkrementellen Speicher aus, hashiert die ByteRange, baut die CMS-SignerInfo (mit denselben signed attributes wie im Browser-Flow: contentType, messageDigest, signingTime, signingCertificateV2 (RFC 5035 ESSCertIDv2 mit issuerSerial) und RFC 6211cmsAlgorithmProtection), holt optional den RFC-3161-Zeitstempel und spleißt ihn als id-aa-signatureTimeStampToken-unsigned-Attribut ein (PAdES-B-T), und liefert das vollständig signierte PDF zurück.
Anfragekörper
{
"credentialID": "codeb-user-a1b2c3d4e5f60718",
"SAD": "<JWT von authorize mit numSignatures ≥ documents.length>",
"documents": [
{
"document": "<base64 PDF Bytes>",
"signature_format": "P",
"conformance_level": "AdES-B-T",
"signed_envelope_property": "Approval",
"container": "No",
"signAlgo": "1.2.840.10045.4.3.2",
"parameters": {
"signing_time": "2026-07-27T10:00:00Z",
"signing_reason": "Ich stimme diesem Vertrag zu",
"signing_location": "Valletta, MT",
"contact_info": "ada@example.org"
}
}
]
}
signAlgo: 1.2.840.10045.4.3.2 (ECDSA-SHA256) oder 1.2.840.113549.1.1.11 (RSA-SHA256).
parameters.signing_reason / signing_location / contact_info landen im PDF-/Sig-Dict als /Reason//Location//ContactInfo.
MVP-Umfangshinweis — SAD-Hash-Bindung für signDoc gelockert.
Gemäß CSC v2 §11.10 sollte das Signature-Activation-Data-(SAD-)JWT an die konkrete(n) zu signierende(n) Hash(es) gebunden sein. Da signDoc die Dokument-Hashes serverseitig berechnet (der Client lädt das gesamte PDF hoch), kann die SAD zum Zeitpunkt von credentials/authorize nicht an diese Hashes vorgebunden werden. Dieser MVP lockert die Prüfung entsprechend: SADs werden auf Signaturgültigkeit, aud=csc-sad, exp / iat-Fenster, sub = Bearer-Subject, credentialID-Match und numSignatures ≥ documents.length geprüft — die konkrete Hash-Liste wird jedoch nicht gegengeprüft. Eine künftige Revision wird den Zwei-Round-Trip-Ablauf (Upload → Hash + Challenge → Autorisierung mit genau diesen Hashes → Abschluss) für strikte Spec-Konformität umsetzen. signHash erzwingt weiterhin die vollständige Hash-Bindung wie von der Spec verlangt. Die Lockerung wird mit [CSC-SIGNDOC-DIAG] SAD_ok (hash-binding relaxed for signDoc) protokolliert und erscheint damit im Audit-Trail.
400 unsupported_signature_format, unsupported_conformance_level, / only signed_envelope_property=Approval supported, / only container=No supported, / unsupported_signAlgo.
400 pdf_encrypted_unsupported — serverseitiges Signieren verschlüsselter PDFs ist verschoben; der Browser-Flow unter sign.html unterstützt Standard Security Handler V2 (RC4-128) und V4 (AES-128).
413 body_too_large — Körper überschreitet das signDoc-Limit von 10 MiB.
RFC-3161-Zeitstempel-Proxy. Der Server baut einen TimeStampReq DER um einen SHA-256-Hash, postet ihn an die konfigurierte TSA, parst die TimeStampResp, extrahiert das TimeStampToken und liefert es base64-kodiert. Der Browser-Signer (sign.html) spleißt dieses Token in die CMS SignerInfo.unsignedAttrs als id-aa-signatureTimeStampToken, was PAdES-B-B zu PAdES-B-T aufwertet.
TSA-URL-Quelle
Die TSA-URL wird aus der Windows-Registry HKLM\SOFTWARE\CodeB, Wert TSAURL, gelesen. Bei leerem/fehlendem Wert wird der Default http://timestamp.sectigo.com/qualified zurückgeschrieben und verwendet. Bei vorhandenem, aber ungültigem Wert liefert der Server 500 invalid_tsa_url statt still zurückzufallen — Operator-Eingriff erforderlich.
Der Browser-Signer schreibt die folgenden Felder. Bei signHash sind sie vollständig client-kontrolliert (Client baut die Hülle). Bei signDoc baut der Server die Dictionary; der Aufrufer liefert Werte über parameters.*.
/Filter /Adobe.PPKLite und /SubFilter /adbe.pkcs7.detached — erzeugt das etsi.CAdES.detached-CMS-Profil, das Adobe Reader als PAdES-B-B akzeptiert.
/Reason — client-kontrolliert (signHash) oder aus parameters.signing_reason (signDoc).