Start · Sprachen · JavaScript · Referenz · WorkerGlobalScope.crypto

WorkerGlobalScope.crypto

Eigenschaft

Die schreibgeschützte Eigenschaft <code>crypto</code> gibt das <code>Crypto</code>-Objekt des Workers zurück, mit Zufallszahlen, UUIDs und der Web Crypto API (<code>crypto.subtle</code>).

seit JavaScript Baseline: alle modernen Browser (Worker-Unterstütz Kategorie: webapi

Signatur

WorkerGlobalScope.crypto

Beschreibung

Über self.crypto (oder kurz crypto) greift man in einem Web Worker, Shared Worker oder Service Worker auf dasselbe Crypto-Objekt zu, das es im Hauptthread als window.crypto gibt. Damit stehen kryptografisch sichere Zufallszahlen (getRandomValues()), UUIDs der Version 4 (randomUUID()) und über crypto.subtle die komplette SubtleCrypto-Schnittstelle zum Hashen, Verschlüsseln, Signieren und Ableiten von Schlüsseln bereit.

Gerade in Workern ist das nützlich: Aufwendige Operationen wie das Hashen großer Dateien, PBKDF2-Schlüsselableitung oder das Ver- und Entschlüsseln von großen Datenmengen blockieren so nicht den UI-Thread. Die Ergebnisse, meist ArrayBuffer, kann man per postMessage() ohne Kopie (als Transferable) an den Hauptthread zurückgeben.

Die Eigenschaft ist schreibgeschützt. Jeder Worker hat eine eigene Crypto-Instanz. CryptoKey-Objekte lassen sich aber per Structured Clone zwischen Hauptthread und Worker verschicken, auch wenn sie nicht exportierbar sind.

Rückgabewert

Typ
Crypto
Beschreibung
Das Crypto-Objekt des aktuellen Worker-Kontexts mit getRandomValues(), randomUUID() und der Eigenschaft subtle (SubtleCrypto).

Beispiele

Zufallswerte und UUID im Worker erzeugen

// worker.js
self.addEventListener('message', () => {
  const bytes = self.crypto.getRandomValues(new Uint8Array(8));
  const id = self.crypto.randomUUID();
  self.postMessage({ id, token: Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('') });
});

// main.js
const worker = new Worker('worker.js');
worker.onmessage = ({ data }) => console.log(data);
worker.postMessage('start');
{ id: '3b241101-e2bb-4255-8caf-4136c566a962', token: '9f1c2a7be04d5531' } (Werte zufällig)

SHA-256-Hash einer Datei im Worker berechnen

// hash-worker.js
self.onmessage = async ({ data: file }) => {
  const buffer = await file.arrayBuffer();
  const digest = await crypto.subtle.digest('SHA-256', buffer);
  const hex = [...new Uint8Array(digest)]
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('');
  self.postMessage(hex);
};

// main.js
const hashWorker = new Worker('hash-worker.js');
hashWorker.onmessage = ({ data }) => console.log('SHA-256:', data);
document.querySelector('input[type=file]').addEventListener('change', (e) => {
  hashWorker.postMessage(e.target.files[0]);
});
SHA-256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 (Beispiel für eine leere Datei)

Passwortbasierte AES-GCM-Verschlüsselung im Worker

// crypto-worker.js
const enc = new TextEncoder();

const deriveKey = async (password, salt) => {
  const base = await crypto.subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveKey']);
  return crypto.subtle.deriveKey(
    { name: 'PBKDF2', salt, iterations: 600000, hash: 'SHA-256' },
    base,
    { name: 'AES-GCM', length: 256 },
    false,
    ['encrypt', 'decrypt']
  );
};

self.onmessage = async ({ data: { password, text } }) => {
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const key = await deriveKey(password, salt);
  const cipher = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, enc.encode(text));
  // ArrayBuffer ohne Kopie übertragen
  self.postMessage({ salt, iv, cipher }, [cipher]);
};
{ salt: Uint8Array(16), iv: Uint8Array(12), cipher: ArrayBuffer(...) }

// Wichtig · Fallstricke

  • Sicherer Kontext: crypto.subtle und crypto.randomUUID() gibt es nur in sicheren Kontexten (HTTPS oder localhost). Sonst ist crypto.subtle undefined. getRandomValues() funktioniert auch ohne sicheren Kontext.
  • Größenlimit: getRandomValues() erzeugt pro Aufruf höchstens 65.536 Bytes, darüber wird ein QuotaExceededError geworfen. Float32Array/Float64Array sind nicht erlaubt.
  • Nicht Math.random() nutzen, wenn es um Tokens, Schlüssel oder IDs mit Sicherheitsbezug geht, denn das ist nicht kryptografisch sicher.
  • AES-GCM: Mit demselben Schlüssel niemals eine IV zweimal verwenden.
  • Kompatibilität: Alle aktuellen Browser unterstützen die Eigenschaft in Dedicated, Shared und Service Workern. randomUUID() gibt es erst seit 2021/2022 (Chrome 92, Firefox 95, Safari 15.4).