Signatur
Beschreibung
EcdsaParams ist keine Klasse, sondern ein Wörterbuch (Dictionary) der Web Crypto API. Man übergibt einfach ein normales Objekt mit den Eigenschaften name und hash an crypto.subtle.sign() oder crypto.subtle.verify(), um digitale Signaturen mit dem Elliptic Curve Digital Signature Algorithm (ECDSA) zu erstellen oder zu prüfen.
Die verwendete Kurve (P-256, P-384 oder P-521) steht nicht in EcdsaParams. Sie wird beim Erzeugen oder Importieren des Schlüssels über EcKeyGenParams bzw. EcKeyImportParams (Eigenschaft namedCurve) festgelegt. In EcdsaParams wählt man nur die Hash-Funktion, mit der die Daten vor dem Signieren zusammengefasst werden.
Typische Einsatzbereiche sind das Signieren von JWTs (ES256, ES384, ES512), WebAuthn-/Passkey-Prüfungen, das Signieren von API-Anfragen und Integritätsprüfungen von Nachrichten zwischen Client und Server. ECDSA liefert bei gleichem Sicherheitsniveau deutlich kürzere Schlüssel und Signaturen als RSA.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Muss "ECDSA" sein (Groß-/Kleinschreibung wird nicht beachtet). |
|
| $hash Pflicht | string | Algorithm | Hash-Funktion, die vor dem Signieren angewendet wird: "SHA-256", "SHA-384" oder "SHA-512", alternativ als Objekt { name: "SHA-256" }. "SHA-1" wird zwar akzeptiert, sollte aber nicht verwendet werden. |
Rückgabewert
EcdsaParams ist ein reines Konfigurationsobjekt. sign() liefert damit ein Promise<ArrayBuffer> (Signatur), verify() ein Promise<boolean>.Beispiele
Schlüsselpaar erzeugen und Nachricht signieren
const keyPair = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-256' },
true,
['sign', 'verify']
);
// EcdsaParams: nur name + hash
const ecdsaParams = { name: 'ECDSA', hash: 'SHA-256' };
const data = new TextEncoder().encode('Bestellung #4711: 3 Artikel');
const signature = await crypto.subtle.sign(ecdsaParams, keyPair.privateKey, data);
console.log(signature.byteLength);
Signatur prüfen und Manipulation erkennen
const { privateKey, publicKey } = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-384' },
false,
['sign', 'verify']
);
const params = { name: 'ECDSA', hash: { name: 'SHA-384' } };
const enc = new TextEncoder();
const signature = await crypto.subtle.sign(params, privateKey, enc.encode('Betrag: 100 EUR'));
const echt = await crypto.subtle.verify(params, publicKey, signature, enc.encode('Betrag: 100 EUR'));
const gefaelscht = await crypto.subtle.verify(params, publicKey, signature, enc.encode('Betrag: 900 EUR'));
console.log(echt, gefaelscht);
JWT-Signatur (ES256) mit importiertem JWK prüfen
const toBytes = (b64url) => Uint8Array.from(
atob(b64url.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0)
);
const verifyJwtES256 = async (jwt, publicJwk) => {
const [header, payload, sig] = jwt.split('.');
const key = await crypto.subtle.importKey(
'jwk', publicJwk,
{ name: 'ECDSA', namedCurve: 'P-256' },
false, ['verify']
);
// JWT nutzt das rohe r||s-Format (IEEE P1363) wie Web Crypto
return crypto.subtle.verify(
{ name: 'ECDSA', hash: 'SHA-256' },
key,
toBytes(sig),
new TextEncoder().encode(`${header}.${payload}`)
);
};
// const ok = await verifyJwtES256(token, jwkVomServer);
// Wichtig · Fallstricke
- Signaturformat: Web Crypto erzeugt und erwartet Signaturen im rohen
r||s-Format (IEEE P1363, bei P-256 64 Byte), nicht DER/ASN.1 wie OpenSSL oder Java. Bei Austausch mit solchen Systemen muss konvertiert werden, sonst liefertverify()stillschweigendfalse. - Kurve und Hash: Die Kurve kommt aus dem Schlüssel, nicht aus
EcdsaParams. Üblich (und für JWT vorgeschrieben) sind die Paare P-256/SHA-256, P-384/SHA-384, P-521/SHA-512. Abweichende Kombinationen funktionieren technisch, sind aber inkompatibel mit Standards. - Nicht deterministisch: ECDSA-Signaturen enthalten Zufall — zwei Signaturen derselben Nachricht unterscheiden sich. Nie Signaturen vergleichen, immer
verify()verwenden. - Nur in sicheren Kontexten (HTTPS,
localhost) verfügbar;crypto.subtleist sonstundefined. - Der Schlüssel muss die passende Verwendung (
'sign'bzw.'verify') besitzen, sonst wird eineInvalidAccessError-Ausnahme ausgelöst. - Für Ed25519 wird nicht
EcdsaParams, sondern{ name: 'Ed25519' }verwendet (neuere Browser).