Start · Sprachen · JavaScript · Referenz · SubtleCrypto.generateKey()

SubtleCrypto.generateKey()

Methode

Erzeugt asynchron einen neuen symmetrischen <code>CryptoKey</code> oder ein asymmetrisches <code>CryptoKeyPair</code> für Verschlüsselung, Signatur oder Schlüsselableitung.

seit JavaScript Baseline: alle modernen Browser (Ed25519/X25519 er Kategorie: webapi

Signatur

SubtleCrypto.prototype.generateKey(algorithm, extractable, keyUsages)

Beschreibung

generateKey() ist die zentrale Methode der Web Crypto API, um kryptografisch sicheres Schlüsselmaterial direkt im Browser (oder in Node.js) zu erzeugen. Für symmetrische Algorithmen wie AES-GCM, AES-CBC, AES-CTR, AES-KW oder HMAC wird ein einzelnes CryptoKey-Objekt geliefert. Für Public-Key-Algorithmen wie RSA-OAEP, RSA-PSS, RSASSA-PKCS1-v1_5, ECDSA, ECDH, Ed25519 oder X25519 erhältst du ein CryptoKeyPair mit publicKey und privateKey.

Welche Felder das algorithm-Objekt enthalten muss, hängt vom Algorithmus ab:

  • AES (AesKeyGenParams): { name, length } mit length 128, 192 oder 256.
  • HMAC (HmacKeyGenParams): { name: "HMAC", hash, length? }.
  • RSA (RsaHashedKeyGenParams): { name, modulusLength, publicExponent, hash }.
  • EC (EcKeyGenParams): { name, namedCurve } mit "P-256", "P-384" oder "P-521".
  • Ed25519 / X25519: nur { name } bzw. der String "Ed25519".

Mit extractable legst du fest, ob der Schlüssel später per exportKey() oder wrapKey() herausgegeben werden darf. keyUsages beschränkt, wofür der Schlüssel verwendet werden kann – ein Versuch, ihn für eine nicht freigegebene Operation zu nutzen, führt zu einem InvalidAccessError. Die Methode steht nur in sicheren Kontexten (HTTPS, localhost) über crypto.subtle zur Verfügung.

Parameter

Name Typ Default Beschreibung
$algorithm Pflicht string | AesKeyGenParams | HmacKeyGenParams | RsaHashedKeyGenParams | EcKeyGenParams | Algorithm Algorithmus und seine Parameter, z. B. { name: "AES-GCM", length: 256 }. Bei Ed25519/X25519 genügt der Name als String.
$extractable Pflicht boolean Ob der Schlüssel mit exportKey() bzw. wrapKey() exportiert werden darf. Bei Schlüsselpaaren ist der öffentliche Schlüssel immer exportierbar, der Wert betrifft nur den privaten Schlüssel.
$keyUsages Pflicht Array<"encrypt"|"decrypt"|"sign"|"verify"|"deriveKey"|"deriveBits"|"wrapKey"|"unwrapKey"> Erlaubte Verwendungszwecke. Müssen zum Algorithmus passen; ein leeres Array (bzw. leere Usages für einen privaten/geheimen Schlüssel) führt zu einem SyntaxError.

Rückgabewert

Typ
Promise<CryptoKey | CryptoKeyPair>
Beschreibung
Promise, das bei symmetrischen Algorithmen mit einem CryptoKey, bei asymmetrischen mit einem CryptoKeyPair ({ publicKey, privateKey }) erfüllt wird. Wird mit SyntaxError abgelehnt, wenn keyUsages leer oder ungültig ist, bzw. mit NotSupportedError, wenn der Algorithmus unbekannt ist.

Beispiele

AES-GCM-Schlüssel erzeugen und Text verschlüsseln

const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true, // exportierbar
  ["encrypt", "decrypt"]
);

const iv = crypto.getRandomValues(new Uint8Array(12)); // pro Nachricht neu!
const daten = new TextEncoder().encode("Geheime Notiz");

const chiffrat = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, daten);
const klartext = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, chiffrat);

console.log(key.type, key.algorithm.length);
console.log(new TextDecoder().decode(klartext));
secret 256 Geheime Notiz

ECDSA-Schlüsselpaar für Signaturen

const { publicKey, privateKey } = await crypto.subtle.generateKey(
  { name: "ECDSA", namedCurve: "P-256" },
  false, // privater Schlüssel bleibt im Browser
  ["sign", "verify"]
);

const nachricht = new TextEncoder().encode("Bestellung #4711");
const signatur = await crypto.subtle.sign(
  { name: "ECDSA", hash: "SHA-256" },
  privateKey,
  nachricht
);

const gueltig = await crypto.subtle.verify(
  { name: "ECDSA", hash: "SHA-256" },
  publicKey,
  signatur,
  nachricht
);
console.log(privateKey.usages, publicKey.usages, gueltig);
["sign"] ["verify"] true

RSA-OAEP-Paar erzeugen und öffentlichen Schlüssel als JWK exportieren

const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]), // 65537
    hash: "SHA-256"
  },
  false,
  ["encrypt", "decrypt"]
);

// Öffentlicher Schlüssel ist trotz extractable=false exportierbar
const jwk = await crypto.subtle.exportKey("jwk", keyPair.publicKey);
console.log(jwk.kty, jwk.alg);
RSA RSA-OAEP-256

HMAC-Schlüssel mit Fehlerbehandlung

const erzeugeHmacKey = async () => {
  try {
    return await crypto.subtle.generateKey(
      { name: "HMAC", hash: "SHA-256" },
      false,
      ["sign", "verify"]
    );
  } catch (err) {
    console.error(`${err.name}: ${err.message}`);
    throw err;
  }
};

const hmacKey = await erzeugeHmacKey();
console.log(hmacKey.algorithm.name, hmacKey.algorithm.length);
HMAC 512

// Wichtig · Fallstricke

  • Sicherer Kontext nötig: crypto.subtle ist auf http://-Seiten (außer localhost) undefined. Prüfe das vorher, statt einen TypeError zu bekommen.
  • Passende Usages: Ungültige Kombinationen (z. B. "encrypt" bei ECDSA) führen zu einem SyntaxError. Bei Schlüsselpaaren werden die Usages automatisch aufgeteilt (sign → privat, verify → öffentlich).
  • extractable: false bevorzugen: Nicht exportierbare Schlüssel lassen sich per IndexedDB speichern (CryptoKey ist strukturiert klonbar), ohne dass Skripte – auch nicht bei XSS – an das Rohmaterial gelangen. Missbrauch durch Angreifer-Code im selben Ursprung verhindert das aber nicht.
  • AES-GCM-IV: Denselben IV nie zweimal mit demselben Schlüssel verwenden – das bricht die Sicherheit vollständig.
  • RSA: publicExponent muss ein Uint8Array sein (üblich: [1, 0, 1]). modulusLength mindestens 2048; die Erzeugung von RSA-4096 kann spürbar dauern.
  • Kompatibilität: AES, HMAC, RSA und ECDSA/ECDH funktionieren in allen modernen Browsern. Ed25519/X25519 sind erst neuerdings überall verfügbar (Chrome 137+, Firefox 129+, Safari 17+) – ggf. per try/catch auf NotSupportedError prüfen. In Node.js über globalThis.crypto.subtle (ab v19 global) bzw. require(\"node:crypto\").webcrypto.subtle.
  • Für Schlüssel aus Passwörtern stattdessen importKey() + deriveKey() mit PBKDF2 verwenden.