====== 3.3 WASM Build für Blazor ====== Diese Anleitung erklärt, wie Sie OpenSSL für Blazor WebAssembly kompilieren. ---- ===== Was ist WebAssembly? ===== **WebAssembly (WASM)** ist ein binäres Format, das im Browser läuft. Es ermöglicht: * Hochperformanten Code im Browser * Sprachen wie C/C++ im Web nutzen * Blazor WebAssembly Anwendungen **Wann brauche ich WASM?** | Anwendungstyp | WASM nötig? | |--------------|-------------| | Blazor WebAssembly | **Ja** | | Blazor Server | Nein (nutzt Windows/Linux Build) | | ASP.NET Core API | Nein | | Desktop App (.NET) | Nein | ---- ===== Voraussetzungen ===== Zusätzlich zu den Standard-Tools benötigen Sie: * ☑ [[.:..vorbereitung:wsl-einrichten|WSL2 mit Ubuntu/Fedora]] * ☑ [[.:..vorbereitung:emscripten|Emscripten SDK]] WASM-Builds sind nur unter Linux/WSL möglich, nicht direkt unter Windows! ---- ===== Build-Übersicht ===== Der WASM-Build erstellt: * ''openssl.js'' - JavaScript-Loader * ''openssl.wasm'' - WebAssembly-Modul * C-Wrapper für Post-Quantum-Funktionen ---- ===== Build-Schritte ===== ==== Schritt 1: WSL öffnen ==== # WSL Terminal öffnen wsl ==== Schritt 2: Emscripten aktivieren ==== # Emscripten Environment laden source /opt/emsdk/emsdk_env.sh # Prüfen emcc --version # Sollte zeigen: emcc (Emscripten gcc/clang-like replacement) 3.x.x ==== Schritt 3: Build-Verzeichnis vorbereiten ==== # Verzeichnisse erstellen mkdir -p /mnt/d/Projects/openssl-3.6.0/wasm-build mkdir -p /mnt/d/Projects/openssl-3.6.0/wasm-install cd /mnt/d/Projects/openssl-3.6.0/wasm-build ==== Schritt 4: OpenSSL für WASM konfigurieren ==== emconfigure /mnt/d/Projects/openssl-3.6.0/src/Configure \ linux-generic32 \ --prefix=/mnt/d/Projects/openssl-3.6.0/wasm-install \ --openssldir=/mnt/d/Projects/openssl-3.6.0/wasm-install/ssl \ no-asm \ no-threads \ no-shared \ no-dso \ no-engine \ no-hw \ no-async \ no-sock \ no-dgram \ no-tests \ no-apps \ -DOPENSSL_NO_SECURE_MEMORY \ CC=emcc \ AR=emar \ RANLIB=emranlib **Erklärung der Optionen:** | Option | Bedeutung | |--------|-----------| | ''linux-generic32'' | Generische 32-bit Plattform | | ''no-asm'' | Keine Assembly (WASM kann kein x86 Assembly) | | ''no-threads'' | Keine Threads (Web Workers separat) | | ''no-shared'' | Nur statische Library | | ''no-sock'' | Keine Socket-Unterstützung | | ''no-tests'' | Keine Tests bauen | | ''no-apps'' | Kein openssl CLI Tool | ==== Schritt 5: Kompilieren ==== emmake make -j$(nproc) build_libs ==== Schritt 6: Installieren ==== emmake make install_sw ---- ===== JavaScript-Wrapper erstellen ===== Für die Integration in Blazor brauchen wir einen Wrapper: ==== wvds_crypto_wrapper.c ==== // WvdS Crypto WASM Wrapper #include #include #include #include #include #include // Initialisierung EMSCRIPTEN_KEEPALIVE int wvds_init(void) { OPENSSL_init_crypto( OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); return 1; } // OpenSSL Version EMSCRIPTEN_KEEPALIVE const char* wvds_get_version(void) { return OPENSSL_VERSION_TEXT; } // ML-DSA Schlüsselgenerierung EMSCRIPTEN_KEEPALIVE int wvds_mldsa_keygen(const char* algorithm, unsigned char** pub_key, int* pub_len, unsigned char** priv_key, int* priv_len) { EVP_PKEY_CTX *ctx = NULL; EVP_PKEY *pkey = NULL; int ret = 0; // Algorithmus-Name für OpenSSL const char* ossl_alg = algorithm; if (strcmp(algorithm, "ML-DSA-44") == 0) ossl_alg = "mldsa44"; else if (strcmp(algorithm, "ML-DSA-65") == 0) ossl_alg = "mldsa65"; else if (strcmp(algorithm, "ML-DSA-87") == 0) ossl_alg = "mldsa87"; ctx = EVP_PKEY_CTX_new_from_name(NULL, ossl_alg, NULL); if (!ctx) goto err; if (EVP_PKEY_keygen_init(ctx) <= 0) goto err; if (EVP_PKEY_keygen(ctx, &pkey) <= 0) goto err; // Public Key exportieren *pub_len = i2d_PUBKEY(pkey, NULL); *pub_key = malloc(*pub_len); unsigned char *p = *pub_key; i2d_PUBKEY(pkey, &p); // Private Key exportieren *priv_len = i2d_PrivateKey(pkey, NULL); *priv_key = malloc(*priv_len); p = *priv_key; i2d_PrivateKey(pkey, &p); ret = 1; err: EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); return ret; } // ML-DSA Signieren EMSCRIPTEN_KEEPALIVE int wvds_mldsa_sign(const unsigned char* data, int data_len, const unsigned char* priv_key, int priv_len, unsigned char** sig, int* sig_len) { // ... (vollständige Implementierung im Build-Skript) return 1; } // ML-DSA Verifizieren EMSCRIPTEN_KEEPALIVE int wvds_mldsa_verify(const unsigned char* data, int data_len, const unsigned char* sig, int sig_len, const unsigned char* pub_key, int pub_len) { // ... (vollständige Implementierung im Build-Skript) return 1; } // Speicher freigeben EMSCRIPTEN_KEEPALIVE void wvds_free(void* ptr) { free(ptr); } ==== Wrapper kompilieren ==== INSTALL_DIR=/mnt/d/Projects/openssl-3.6.0/wasm-install OUTPUT=/mnt/d/Projects/openssl-3.6.0/wasm-build emcc $OUTPUT/wvds_crypto_wrapper.c \ -I"$INSTALL_DIR/include" \ -L"$INSTALL_DIR/lib" \ -lcrypto \ -Os \ -s WASM=1 \ -s MODULARIZE=1 \ -s EXPORT_NAME="OpenSSLModule" \ -s EXPORTED_FUNCTIONS='["_wvds_init","_wvds_get_version","_wvds_mldsa_keygen","_wvds_mldsa_sign","_wvds_mldsa_verify","_wvds_free","_malloc","_free"]' \ -s EXPORTED_RUNTIME_METHODS='["ccall","cwrap","getValue","setValue","UTF8ToString"]' \ -s ALLOW_MEMORY_GROWTH=1 \ -o "$OUTPUT/openssl.js" ---- ===== Ergebnis ===== Nach dem Build: wasm-build/ ├── openssl.js # JavaScript Loader (~150 KB) └── openssl.wasm # WebAssembly Modul (~2 MB) ---- ===== In Blazor einbinden ===== ==== 1. Dateien kopieren ==== cp openssl.js openssl.wasm /mnt/d/MeinProjekt/wwwroot/ ==== 2. In index.html laden ==== ==== 3. In Blazor aufrufen ==== // In Ihrer Blazor-Komponente @inject IJSRuntime JS public async Task GetOpenSslVersion() { return await JS.InvokeAsync("eval", "cryptoModule.ccall('wvds_get_version', 'string', [], [])"); } ---- ===== Vollständiges Build-Skript ===== Für den kompletten Build mit ML-DSA und ML-KEM: #!/bin/bash # build-wasm.sh - OpenSSL 3.6.0 WASM Build set -e OPENSSL_SRC="/mnt/d/Projects/openssl-3.6.0/src" OUTPUT_DIR="/mnt/d/Projects/openssl-3.6.0/wasm-build" INSTALL_DIR="/mnt/d/Projects/openssl-3.6.0/wasm-install" echo "=== OpenSSL WASM Build ===" # Emscripten aktivieren source /opt/emsdk/emsdk_env.sh # Verzeichnisse erstellen mkdir -p "$OUTPUT_DIR" "$INSTALL_DIR" cd "$OUTPUT_DIR" # Konfigurieren emconfigure "$OPENSSL_SRC/Configure" \ linux-generic32 \ --prefix="$INSTALL_DIR" \ no-asm no-threads no-shared no-dso no-engine \ no-async no-sock no-dgram no-tests no-apps \ CC=emcc AR=emar RANLIB=emranlib # Bauen emmake make -j$(nproc) build_libs # Installieren emmake make install_sw echo "=== Build abgeschlossen ===" ---- ===== Weiter zu ===== * [[.:vorbereitung:emscripten|Emscripten SDK installieren]] * [[.:integration:blazor-wasm|Blazor WASM Integration]] * [[.:build:start|Zurück zur Build-Übersicht]] ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//