Signatur
Beschreibung
EcKeyGenParams ist keine Klasse, die man instanziiert. Es ist ein Wörterbuch (dictionary) des Web Crypto API und damit einfach ein normales Objekt-Literal. Man übergibt es als ersten Parameter an crypto.subtle.generateKey(), wenn ein Schlüsselpaar auf Basis elliptischer Kurven erzeugt werden soll: ECDSA zum Signieren und Prüfen oder ECDH zur Schlüsselvereinbarung.
Das Objekt hat genau zwei Eigenschaften: name ("ECDSA" oder "ECDH") und namedCurve ("P-256", "P-384" oder "P-521"). Weil ein asymmetrisches Verfahren entsteht, liefert generateKey() ein CryptoKeyPair mit publicKey und privateKey.
Im Vergleich zu RSA sind EC-Schlüssel viel kürzer, bei vergleichbarer Sicherheit. Sie werden außerdem schneller erzeugt. P-256 ist der übliche Standard, z. B. für JWT mit ES256, WebAuthn oder verschlüsselte Ende-zu-Ende-Kommunikation. Die Kurven X25519 und Ed25519 nutzen nicht EcKeyGenParams. Für sie reicht ein Objekt mit nur name.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Name des Algorithmus: "ECDSA" für Signaturen oder "ECDH" für die Schlüsselvereinbarung. |
|
| $namedCurve Pflicht | "P-256" | "P-384" | "P-521" | Name der NIST-Kurve. P-256 (secp256r1) ist am weitesten verbreitet. P-384 und P-521 bieten ein höheres Sicherheitsniveau. |
Rückgabewert
generateKey() gibt damit ein Promise<CryptoKeyPair> zurück.Beispiele
ECDSA-Schlüsselpaar erzeugen und Daten signieren
const keyPair = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-256' }, // EcKeyGenParams
true, // exportierbar
['sign', 'verify']
);
const data = new TextEncoder().encode('Bestellung #4711');
const signature = await crypto.subtle.sign(
{ name: 'ECDSA', hash: 'SHA-256' },
keyPair.privateKey,
data
);
const valid = await crypto.subtle.verify(
{ name: 'ECDSA', hash: 'SHA-256' },
keyPair.publicKey,
signature,
data
);
console.log(signature.byteLength, valid);
ECDH: gemeinsames Geheimnis zweier Parteien ableiten
const params = { name: 'ECDH', namedCurve: 'P-384' };
const alice = await crypto.subtle.generateKey(params, false, ['deriveKey']);
const bob = await crypto.subtle.generateKey(params, false, ['deriveKey']);
const deriveAes = (priv, pub) => crypto.subtle.deriveKey(
{ name: 'ECDH', public: pub },
priv,
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
const keyA = await deriveAes(alice.privateKey, bob.publicKey);
const keyB = await deriveAes(bob.privateKey, alice.publicKey);
const rawA = new Uint8Array(await crypto.subtle.exportKey('raw', keyA));
const rawB = new Uint8Array(await crypto.subtle.exportKey('raw', keyB));
console.log(rawA.every((b, i) => b === rawB[i]));
Öffentlichen Schlüssel als JWK exportieren
const { publicKey } = await crypto.subtle.generateKey(
{ name: 'ECDSA', namedCurve: 'P-256' },
true,
['sign', 'verify']
);
const jwk = await crypto.subtle.exportKey('jwk', publicKey);
console.log(jwk.kty, jwk.crv, publicKey.algorithm);
// Wichtig · Fallstricke
- Nur in sicheren Kontexten:
crypto.subtlegibt es nur über HTTPS oder auflocalhost. Sonst ist esundefined. - Key-Usages beachten: ECDSA erlaubt nur
sign/verify, ECDH nurderiveKey/deriveBits. Falsche Werte führen zu einemSyntaxError. Eine unbekannte Kurve löst einenNotSupportedErroraus. - Den Hash (z. B.
SHA-256) gibt man nicht bei der Erzeugung an. Er wird erst beisign()/verify()überEcdsaParamsübergeben. - ECDSA-Signaturen liegen im Format IEEE P1363 vor (r‖s, bei P-256 64 Byte) und nicht DER-kodiert. Für den Austausch mit OpenSSL, Java usw. muss man sie gegebenenfalls umwandeln.
- Private Schlüssel am besten mit
extractable: falseerzeugen und bei Bedarf alsCryptoKeyin IndexedDB speichern. So bleibt das Schlüsselmaterial für Skripte unzugänglich. - Die Kurve
secp256k1(Bitcoin) wird nicht unterstützt.