Start · Sprachen · JavaScript · Referenz · CryptoKey.extractable

CryptoKey.extractable

Eigenschaft

Schreibgeschützter boolescher Wert, der angibt, ob ein <code>CryptoKey</code> per <code>SubtleCrypto.exportKey()</code> oder <code>SubtleCrypto.wrapKey()</code> exportiert werden darf.

seit JavaScript Baseline: alle modernen Browser (Web Crypto API), Kategorie: webapi

Signatur

CryptoKey.extractable

Beschreibung

Die Eigenschaft extractable eines CryptoKey-Objekts zeigt, ob man das Schlüsselmaterial aus der Web Crypto API herausholen darf. Ist sie true, lässt sich der Schlüssel mit SubtleCrypto.exportKey() in ein Format wie raw, pkcs8, spki oder jwk exportieren oder mit SubtleCrypto.wrapKey() verschlüsselt verpacken. Ist sie false, werden beide Operationen mit einer InvalidAccessError-DOMException abgelehnt.

Der Wert wird einmal beim Erzeugen des Schlüssels festgelegt, und zwar über den Parameter extractable von generateKey(), importKey(), deriveKey() oder unwrapKey(). Danach lässt er sich nicht mehr ändern. Nicht exportierbare Schlüssel sind das empfohlene Standardvorgehen: Selbst wenn eingeschleuster Schadcode (XSS) Zugriff auf das Objekt bekommt, kann er das Schlüsselmaterial nicht auslesen, sondern den Schlüssel nur im Rahmen seiner usages verwenden.

Typisch ist das in folgenden Fällen:

  • Man prüft vor einem Exportversuch, ob der Export überhaupt möglich ist.
  • Man erzeugt Sitzungsschlüssel, die nie den Browser verlassen sollen, und speichert sie als CryptoKey-Objekt in IndexedDB.
  • Man fragt die Eigenschaft in Tests oder Audits ab, um sicherzustellen, dass kein privater Schlüssel versehentlich exportierbar erzeugt wurde.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn der Schlüssel exportiert oder verpackt werden darf, sonst false.

Beispiele

Exportierbaren AES-Schlüssel erzeugen und exportieren

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

console.log(key.extractable);

if (key.extractable) {
  const raw = await crypto.subtle.exportKey('raw', key);
  console.log(raw.byteLength);
}
true 32

Nicht exportierbarer Schlüssel: Export schlägt fehl

const key = await crypto.subtle.generateKey(
  { name: 'HMAC', hash: 'SHA-256' },
  false, // nicht exportierbar
  ['sign', 'verify']
);

console.log(key.extractable);

try {
  await crypto.subtle.exportKey('jwk', key);
} catch (err) {
  console.log(err.name);
}
false InvalidAccessError

Schlüsselpaar: öffentlicher Schlüssel bleibt immer exportierbar

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

console.log('public:', publicKey.extractable);
console.log('private:', privateKey.extractable);

// Öffentlichen Schlüssel an den Server senden
const spki = await crypto.subtle.exportKey('spki', publicKey);
console.log(spki.byteLength);
public: true private: false 91

Nicht exportierbaren Schlüssel sicher in IndexedDB ablegen

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

const db = await new Promise((resolve, reject) => {
  const req = indexedDB.open('keystore', 1);
  req.onupgradeneeded = () => req.result.createObjectStore('keys');
  req.onsuccess = () => resolve(req.result);
  req.onerror = () => reject(req.error);
});

// CryptoKey ist strukturiert klonbar – das Material bleibt verborgen
db.transaction('keys', 'readwrite').objectStore('keys').put(key, 'session');
console.log('gespeichert, extractable =', key.extractable);
gespeichert, extractable = false

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung wie key.extractable = true bewirkt nichts (im Strict Mode gibt es einen TypeError). Wer einen exportierbaren Schlüssel braucht, muss ihn neu erzeugen oder importieren.
  • Öffentliche Schlüssel: Bei generateKey() für asymmetrische Verfahren ist der publicKey unabhängig vom Parameter immer extractable: true. Der Parameter gilt nur für den privaten Schlüssel.
  • Sicherheit: extractable: false schützt das Schlüsselmaterial vor dem Auslesen, aber nicht vor Missbrauch. Schadcode mit Zugriff auf das Objekt kann damit weiterhin signieren oder entschlüsseln. Die Berechtigungen deshalb zusätzlich über usages möglichst eng halten.
  • Abgeleitete Schlüssel: Bei deriveKey() und unwrapKey() legt der eigene extractable-Parameter den Wert des neuen Schlüssels fest. Er wird nicht vom Basisschlüssel übernommen.
  • Kompatibilität: Die Web Crypto API steht nur in sicheren Kontexten (HTTPS, localhost) zur Verfügung. In Node.js ist sie über require('node:crypto').webcrypto bzw. ab Version 19 global über crypto.subtle erreichbar.