====== 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//