Ta navodila razlagajo, kako prevesti OpenSSL za Blazor WebAssembly.
WebAssembly (WASM) je binarni format, ki teče v brskalniku. Omogoča:
Kdaj potrebujem WASM?
| Tip aplikacije | WASM potreben? |
| —————- | —————- |
| Blazor WebAssembly | Da |
| Blazor Server | Ne (uporabi Windows/Linux gradnjo) |
| ASP.NET Core API | Ne |
| Namizna aplikacija (.NET) | Ne |
Poleg standardnih orodij potrebujete:
WASM gradnje so možne samo pod Linux/WSL, ne neposredno pod Windows!
WASM gradnja ustvari:
openssl.js - JavaScript nalagalnikopenssl.wasm - WebAssembly modul# Odprite WSL terminal
wsl
# Naložite Emscripten okolje source /opt/emsdk/emsdk_env.sh # Preverjanje emcc --version # Prikazati bi moralo: emcc (Emscripten gcc/clang-like replacement) 3.x.x
# Ustvarjanje imenikov 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
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
Razlaga možnosti:
| Možnost | Pomen |
| ——— | ——- |
linux-generic32 | Generična 32-bitna platforma |
no-asm | Brez assembly (WASM ne more x86 assembly) |
no-threads | Brez niti (Web Workers ločeno) |
no-shared | Samo statična knjižnica |
no-sock | Brez podpore za vtičnice |
no-tests | Brez gradnje testov |
no-apps | Brez openssl CLI orodja |
emmake make -j$(nproc) build_libs
emmake make install_sw
Za integracijo v Blazor potrebujemo ovoj:
// WvdS Crypto WASM Wrapper #include <emscripten.h> #include <openssl/evp.h> #include <openssl/x509.h> #include <openssl/err.h> #include <string.h> #include <stdlib.h> // Inicializacija 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 različica EMSCRIPTEN_KEEPALIVE const char* wvds_get_version(void) { return OPENSSL_VERSION_TEXT; } // ML-DSA generiranje ključev 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; // Ime algoritma za 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; // Izvoz javnega ključa *pub_len = i2d_PUBKEY(pkey, NULL); *pub_key = malloc(*pub_len); unsigned char *p = *pub_key; i2d_PUBKEY(pkey, &p); // Izvoz zasebnega ključa *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 podpisovanje 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) { // ... (popolna implementacija v skripti za gradnjo) return 1; } // ML-DSA preverjanje 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) { // ... (popolna implementacija v skripti za gradnjo) return 1; } // Sprostitev pomnilnika EMSCRIPTEN_KEEPALIVE void wvds_free(void* ptr) { free(ptr); }
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"
Po gradnji:
wasm-build/ ├── openssl.js # JavaScript nalagalnik (~150 KB) └── openssl.wasm # WebAssembly modul (~2 MB)
cp openssl.js openssl.wasm /mnt/d/MojProjekt/wwwroot/
<script src="openssl.js"></script> <script> var cryptoModule = null; OpenSSLModule().then(function(module) { cryptoModule = module; module._wvds_init(); console.log("OpenSSL Version:", module.ccall('wvds_get_version', 'string', [], [])); }); </script>
// V vaši Blazor komponenti @inject IJSRuntime JS public async Task<string> GetOpenSslVersion() { return await JS.InvokeAsync<string>("eval", "cryptoModule.ccall('wvds_get_version', 'string', [], [])"); }
Za popolno gradnjo z ML-DSA in 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 ===" # Aktivacija Emscripten source /opt/emsdk/emsdk_env.sh # Ustvarjanje imenikov mkdir -p "$OUTPUT_DIR" "$INSTALL_DIR" cd "$OUTPUT_DIR" # Konfiguracija 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 # Gradnja emmake make -j$(nproc) build_libs # Namestitev emmake make install_sw echo "=== Gradnja končana ==="
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional