WebAssembly-Verschlüsselung: nahezu native Krypto-Geschwindigkeit
Nutzen Sie WebAssembly für nahezu native Verschlüsselungsgeschwindigkeiten. Vergleichen Sie WASM-Crypto-Implementierungen.
WASM-kompilierte Krypto-Bibliotheken laufen im Browser bei etwa 60–80 % nativer C-Geschwindigkeit, was 3–10× schneller ist als reine JavaScript-Implementierungen. Für Verschlüsselungsprimitive, die in der Web Crypto API fehlen (ChaCha20-Poly1305, Argon2id, XChaCha20, Post-Quantum-KEMs wie Kyber), ist WASM der praktische Weg zu nutzbarer Performance. libsodium.js ist die dominante Option und bietet die vollständige libsodium-API mit einem 200-KB-WASM-Binary. Für durch Web Crypto unterstützte Primitive wie AES-256-GCM schlägt die native hardwarebeschleunigte Browser-Implementierung WASM deutlich — WASM ist also nicht immer das richtige Werkzeug. Dieser Leitfaden behandelt, wann Sie dazu greifen sollten und wie Sie die Trade-offs benchmarken.
Wann native Web Crypto gewinnt
Für Algorithmen, die Web Crypto bereits bereitstellt — AES-GCM, AES-CBC, AES-CTR, PBKDF2, HMAC, RSA-OAEP, ECDH, ECDSA, SHA-256/384/512 — nutzt die native Browser-Implementierung Hardwarebeschleunigung via AES-NI auf x86 und ARMv8-Crypto-Extensions auf Mobile. Typischer AES-256-GCM-Durchsatz:
- Web Crypto (Chrome auf Apple Silicon): 1,7 GB/s
- Web Crypto (Chrome auf Intel x86 mit AES-NI): 1,2 GB/s
- libsodium WASM AES-GCM: 400–800 MB/s
- Natives OpenSSL als Referenz: 3–5 GB/s
WASM hat innerhalb der Sandbox keinen Zugriff auf AES-NI; es fällt auf bitsliced-AES-Implementierungen zurück, die langsamer, aber constant-time sind. Für alles, was Web Crypto unterstützt, verwenden Sie das zuerst.
Wo WASM gewinnt
Für Algorithmen, die Web Crypto fehlen:
- ChaCha20-Poly1305: schneller als AES auf Geräten ohne AES-NI. Keine native Browser-Unterstützung im Jahr 2026.
- XChaCha20-Poly1305: 192-Bit-Nonces machen Zufalls-Nonce-Nutzung bei jeder Skalierung sicher.
- Argon2id: die PHC-preisgekrönte Passwort-Hash-Funktion. Keine native Browser-Unterstützung.
- X25519 / Ed25519: Safari 17 und Firefox 129 haben native Unterstützung hinzugefügt, aber WASM ist weiterhin der portable Weg.
- BLAKE2b / BLAKE3: schnelle Hash-Funktionen, die nicht in Web Crypto enthalten sind.
- Kyber, Dilithium, SPHINCS+: Post-Quantum-Primitive; ausschließlich Bibliotheksgebiet.
- Streaming AEAD: libsodiums
crypto_secretstreamhandhabt Streaming-Verschlüsselung großer Dateien sauber; Web Crypto hat kein Äquivalent.
Für diese gibt es JavaScript-Implementierungen, die aber 5–20× langsamer als WASM sind. Bei einer 1-GB-Datei mit ChaCha20-Poly1305 läuft WASM in ~2 Sekunden, während reines JS 15–40 Sekunden braucht.
libsodium.js: Der Arbeitstier
libsodium-wrappers (das Emscripten-kompilierte libsodium mit JS-Wrappern) ist die bevorzugte Bibliothek. 200 KB WASM + ~50 KB JS-Wrapper, gzip-komprimiert.
import _sodium from 'libsodium-wrappers';
await _sodium.ready;
const sodium = _sodium;
// ChaCha20-Poly1305 authentifizierte Verschlüsselung
const key = sodium.crypto_aead_xchacha20poly1305_ietf_keygen();
const nonce = sodium.randombytes_buf(sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES);
const ciphertext = sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
plaintext, null, null, nonce, key
);
Der „Sumo"-Build (enthält mehr Algorithmen) ist ~600 KB; der Standard-Build deckt 90 % der Anwendungsfälle ab, einschließlich AEAD, Passwort-Hashing (Argon2id), X25519 und Ed25519.
Laden Sie dynamisch, damit das WASM-Binary das initiale Seiten-Rendering nicht blockiert:
async function getSodium() {
if (!window._sodium) {
const mod = await import('libsodium-wrappers');
await mod.ready;
window._sodium = mod;
}
return window._sodium;
}
Streaming AEAD via crypto_secretstream
Für große Dateiübertragungen ist libsodiums crypto_secretstream_xchacha20poly1305 das sauberste Streaming-AEAD im Browser:
const { state, header } = sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
const chunk1 = sodium.crypto_secretstream_xchacha20poly1305_push(
state, plaintext1, null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE
);
// Letzter Chunk verwendet TAG_FINAL, damit der Empfänger Abschneidungen erkennt
const chunkLast = sodium.crypto_secretstream_xchacha20poly1305_push(
state, plaintextLast, null,
sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
);
Der TAG_FINAL-Marker ermöglicht dem Empfänger, Abschneideangriffe zu erkennen — wenn ein Angreifer abschließende Chunks verwirft, schlägt die clientseitige Entschlüsselung fehl. AES-GCM in Web Crypto hat diese Eigenschaft nicht; Sie müssten Abschneideerkennung selbst bauen (Chunk-Anzahl in AAD oder ein gesamter Datei-Hash, der nach der Entschlüsselung verifiziert wird).
Argon2 im Browser
Für passwortbasierte Schlüsselableitung im Browser ist Argon2id via WASM die Best Practice für 2026. Optionen:
- argon2-browser: dedizierte Argon2-WASM-Bibliothek, ~200 KB
- libsodium.js: Argon2id via
crypto_pwhash, wenn Sie libsodium ohnehin verwenden - @noble/hashes: reines JS Argon2id, ~15 KB Bundle, 3–5× langsamer als WASM
Beispiel mit argon2-browser:
import argon2 from 'argon2-browser';
const result = await argon2.hash({
pass: password,
salt: salt, // Uint8Array, 16+ Bytes
type: argon2.ArgonType.Argon2id,
time: 3,
mem: 65536, // KiB, also 64 MiB
parallelism: 4,
hashLen: 32,
});
// result.hash ist ein Uint8Array, den Sie als AES-256-Schlüssel verwenden können
Kalibrieren Sie Parameter auf die Wartebereitschaft Ihrer Zielnutzer. OWASP-2024-Ausgangsbasis (m=19 MiB, t=2, p=1) läuft in ~300–500 ms. Stärker (m=64 MiB, t=3, p=4) läuft in ~1–2 Sekunden auf moderner Hardware.
Post-Quantum-Krypto via WASM
Kyber (Key-Encapsulation) und Dilithium (Signaturen) wurden 2024 von NIST als ML-KEM und ML-DSA standardisiert. JavaScript-Implementierungen existieren (pq-crystals hat eine Referenz), aber WASM-Versionen wie liboqs-js sind schneller und auditierbarer.
Für Dateiübertragungen lassen Post-Quantum-KEMs zu, einen symmetrischen Datei-Schlüssel mit einem quantensicheren Public-Key-Primitiv zu verpacken. Hybride Schemata (ML-KEM + X25519) schützen gegen klassische und zukünftige Quanten-Angreifer. Chrome hat ML-KEM in TLS-Handshakes in Version 116 (2023) eingeführt, aber anwendungsseitiges WASM bleibt der Weg für Datei-Inhaltsschlüssel.
Bundle-Größen-Überlegungen
WASM-Binaries werden als Teil Ihres JS-Bundles geliefert oder lazy geladen. Ungefähre Größen (gzip-komprimiert):
- libsodium.js Standard: 200 KB
- libsodium.js Sumo: 600 KB
- argon2-browser: 200 KB
- liboqs-js (Post-Quantum): 1 MB+
Für eine Landing Page, die im Browser verschlüsselt, sind 200–300 KB WASM tolerierbar, wenn sie nach Nutzerinteraktion lazy geladen werden. Für eine App, die Verschlüsselung als Hauptfunktion hat, ist das Mitliefern von WASM beim initialen Laden vernünftig. Verwenden Sie rel="modulepreload"-Hints oder Service-Worker-Caching, um nachfolgende Ladezeiten sofort zu halten.
Überprüfen Sie den Netzwerk-Tab in den Browser-DevTools, um zu bestätigen, dass das WASM-Binary nach dem ersten Laden gecacht wird. Falsch konfigurierte Cache-Header können bei jedem Besuch zu erneuten Downloads führen.
Kompilierungs- und Instanziierungs-Overhead
WebAssembly.instantiate() parst und kompiliert das Binary, was 20–100 ms für ein 200-KB-Modul auf Desktop und 100–500 ms auf Mobile dauert. Das passiert einmal pro Session. Cachen Sie das kompilierte Modul in IndexedDB via WebAssembly.Module-Serialisierung für schnelleres nachfolgendes Laden.
WebAssembly.instantiateStreaming() pipelined Download und Kompilierung und spart 30–50 % der Startzeit im Vergleich zu instantiate() bei einer geholten Antwort:
const response = fetch('/sodium.wasm');
const { instance } = await WebAssembly.instantiateStreaming(response, importObject);
Speicherverwaltungs-Fallstricke
WASM-Module allozieren Speicher in linearen Seiten (je 64 KiB). libsodium startet mit kleinem initialem Speicher und wächst nach Bedarf, aber unbegrenztes Wachstum kann Browser-Limits treffen (typisch 4 GB lineares Speicherlimit in 32-Bit-WASM). Für Multi-GB-Dateiverschlüsselung:
- Streamen Sie Chunks durch das WASM-Modul, laden Sie nicht die gesamte Datei in WASM-Speicher
- Geben Sie Buffer nach jedem Chunk via
sodium.memzerooder durch Null-Setzen von Referenzen frei - Überwachen Sie
WebAssembly.Memory.buffer.byteLengthin lang laufenden Sessions
Memory64 (vorgeschlagen, teilweise in Chrome implementiert) entfernt das 4-GB-Limit. Vorerst ist Chunk-Verarbeitung der zuverlässige Weg.
Sicherheitsüberlegungen spezifisch für WASM
WASM läuft im selben Origin wie die Seite, die es geladen hat, und erbt dieselben CSP- und CORS-Regeln. Wenn ein Angreifer Code in Ihren Origin injiziert (XSS), kann er in Ihr WASM-Modul-Exports aufrufen. WASM bietet keine zusätzliche Sicherheitsgrenze.
Constant-Time-Garantien: Die meisten Krypto-Bibliotheken, die nach WASM kompiliert werden, behalten Constant-Time-Eigenschaften aus dem C-Quellcode bei, aber die WASM-zu-JIT-Übersetzung kann auf einigen Plattformen variabel-zeitigen Code einführen. Audit-Logs von libsodium vermerken einige WASM-spezifische Constant-Time-Bedenken. Für die meisten Bedrohungsmodelle ist das vernachlässigbar; für die Abwehr gegen lokale Angreifer mit präzisen Timing-Messungen sollten Sie die Lücke berücksichtigen.
Das praktische Rezept
Für eine Dateiübertragungsapp im Jahr 2026:
- Web Crypto für AES-256-GCM, PBKDF2, HMAC, SHA-256, RSA-OAEP falls RSA benötigt
- libsodium.js via WASM für Argon2id-Passwort-Hashing
- libsodium.js für Streaming-Verschlüsselung großer Dateien (
crypto_secretstream) - Natives Ed25519/X25519 wo unterstützt, ansonsten libsodium als Fallback
- WASM nach Nutzerinteraktion lazy laden, um den initialen Bundle schlank zu halten
- Auf Zielgeräten benchmarken; gehen Sie nicht davon aus, dass Desktop-Zahlen Mobile entsprechen
HexaTransfer bleibt bei Web Crypto AES-GCM für die Massendateiverschlüsselung, weil der hardwarebeschleunigte Weg am schnellsten ist. WASM ist reserviert für Algorithmen, die native APIs nicht liefern können.
Auf hexatransfer.com testen — kostenlos, ohne Konto, bis 10 GB.
Große Dateien sicher mit Ende-zu-Ende-Verschlüsselung senden
Übertragen Sie Dateien bis zu 10 GB kostenlos mit Ende-zu-Ende-Verschlüsselung. Kein Konto erforderlich. Ihre Dateien werden in Ihrem Browser verschlüsselt, bevor sie hochgeladen werden — niemand sonst kann sie lesen.
Datei senden