Start · Sprachen · JavaScript · Referenz · CryptoKeyPair

CryptoKeyPair

Schnittstelle

Dictionary der Web Crypto API mit einem zusammengehörigen öffentlichen und privaten Schlüssel (<code>publicKey</code>, <code>privateKey</code>) für asymmetrische Algorithmen.

seit JavaScript Baseline: alle modernen Browser (sicherer Kontext Kategorie: webapi

Signatur

interface CryptoKeyPair { publicKey: CryptoKey; privateKey: CryptoKey }

Beschreibung

CryptoKeyPair ist ein einfaches Dictionary (kein Konstruktor, keine Klasse) der Web Crypto API. Es enthält zwei CryptoKey-Objekte: publicKey (öffentlicher Schlüssel) und privateKey (privater Schlüssel). Ein solches Objekt erhältst du als aufgelösten Wert von crypto.subtle.generateKey(), wenn du einen asymmetrischen Algorithmus wie RSA-OAEP, RSA-PSS, RSASSA-PKCS1-v1_5, ECDSA, ECDH, Ed25519 oder X25519 angibst.

Den öffentlichen Schlüssel darfst du weitergeben, zum Beispiel an einen Server oder Kommunikationspartner. Mit ihm werden Daten verschlüsselt (RSA-OAEP) oder Signaturen geprüft (ECDSA, RSA-PSS, Ed25519). Der private Schlüssel bleibt geheim und dient zum Entschlüsseln, Signieren oder zum Ableiten gemeinsamer Geheimnisse (ECDH/X25519).

Wofür welcher Schlüssel verwendet werden darf, bestimmt das keyUsages-Array, das du beim Erzeugen angibst. Die Web Crypto API verteilt es automatisch auf die passenden Schlüssel, z. B. "sign" auf den privaten und "verify" auf den öffentlichen Schlüssel. Der Parameter extractable gilt nur für den privaten Schlüssel. Der öffentliche Schlüssel ist immer exportierbar.

Parameter

Name Typ Default Beschreibung
$publicKey Pflicht CryptoKey Öffentlicher Schlüssel (type === "public"). Ist immer exportierbar. Verwendungszwecke z. B. "encrypt", "verify", "wrapKey".
$privateKey Pflicht CryptoKey Privater Schlüssel (type === "private"). Verwendungszwecke z. B. "decrypt", "sign", "deriveKey", "deriveBits", "unwrapKey". Ob er exportierbar ist, bestimmt extractable.

Rückgabewert

Typ
CryptoKeyPair
Beschreibung
Wird als aufgelöster Wert von crypto.subtle.generateKey() bei asymmetrischen Algorithmen geliefert: Promise<CryptoKeyPair>.

Beispiele

ECDSA-Schlüsselpaar erzeugen und Daten signieren

const keyPair = await crypto.subtle.generateKey(
  { name: 'ECDSA', namedCurve: 'P-256' },
  false,               // privater Schlüssel nicht exportierbar
  ['sign', 'verify']
);

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

const gueltig = await crypto.subtle.verify(
  { name: 'ECDSA', hash: 'SHA-256' },
  keyPair.publicKey,
  signatur,
  daten
);

console.log(keyPair.publicKey.type, keyPair.privateKey.type);
console.log(keyPair.privateKey.usages, keyPair.publicKey.usages);
console.log('Signatur gültig:', gueltig);
public private ["sign"] ["verify"] Signatur gültig: true

RSA-OAEP: Verschlüsseln mit publicKey, Entschlüsseln mit privateKey

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

const klartext = new TextEncoder().encode('Geheime Nachricht');
const chiffrat = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, publicKey, klartext);
const entschluesselt = await crypto.subtle.decrypt({ name: 'RSA-OAEP' }, privateKey, chiffrat);

console.log(new TextDecoder().decode(entschluesselt));
Geheime Nachricht

Öffentlichen Schlüssel als JWK exportieren (z. B. für den Server)

const keyPair = await crypto.subtle.generateKey(
  { name: 'ECDH', namedCurve: 'P-256' },
  false,
  ['deriveKey', 'deriveBits']
);

// publicKey ist immer exportierbar, auch bei extractable = false
const jwk = await crypto.subtle.exportKey('jwk', keyPair.publicKey);
console.log(jwk.kty, jwk.crv);

// privateKey mit extractable = false lässt sich nicht exportieren
try {
  await crypto.subtle.exportKey('jwk', keyPair.privateKey);
} catch (err) {
  console.log(err.name);
}
EC P-256 InvalidAccessError

Schlüsselpaar dauerhaft in IndexedDB ablegen

const oeffneDb = () => new Promise((resolve, reject) => {
  const req = indexedDB.open('schluessel', 1);
  req.onupgradeneeded = () => req.result.createObjectStore('paare');
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

const keyPair = await crypto.subtle.generateKey(
  { name: 'ECDSA', namedCurve: 'P-256' },
  false,
  ['sign', 'verify']
);

const db = await oeffneDb();
const tx = db.transaction('paare', 'readwrite');
// CryptoKey-Objekte sind strukturiert klonbar, also direkt speicherbar
tx.objectStore('paare').put(keyPair, 'geraet');
tx.oncomplete = () => console.log('Schlüsselpaar gespeichert');
Schlüsselpaar gespeichert

// Wichtig · Fallstricke

  • Kein Konstruktor: new CryptoKeyPair() gibt es nicht. Das Dictionary entsteht nur durch crypto.subtle.generateKey() mit einem asymmetrischen Algorithmus. Symmetrische Algorithmen wie AES oder HMAC liefern stattdessen einen einzelnen CryptoKey.
  • Nur Schlüsselerzeugung: importKey() liefert immer einen einzelnen CryptoKey. Ein Paar importierst du mit zwei getrennten Aufrufen.
  • extractable gilt nur für den privaten Schlüssel. Setze ihn auf false, wenn der private Schlüssel das Gerät nie verlassen soll. In Kombination mit IndexedDB lässt sich das Paar trotzdem dauerhaft speichern, weil CryptoKey strukturiert klonbar ist.
  • Falsche keyUsages (z. B. "encrypt" bei ECDSA) oder ein leeres Nutzungs-Array beim privaten Schlüssel führen zu einem SyntaxError.
  • Sicherer Kontext: crypto.subtle steht nur unter HTTPS oder localhost zur Verfügung, sonst ist es undefined.
  • Kompatibilität: RSA- und EC-Algorithmen funktionieren in allen modernen Browsern. Ed25519 und X25519 sind erst seit Kurzem überall verfügbar (Chrome 137+, Firefox 129+/130+, Safari 17+). Prüfe vorher, ob sie unterstützt werden. In Node.js nutzt du globalThis.crypto.subtle (ab 15 über require('node:crypto').webcrypto).
  • Leistung: Das Erzeugen von RSA-Schlüsseln mit 4096 Bit kann spürbar dauern. EC-Schlüssel sind deutlich schneller erzeugt und kürzer.