3.3 WASM gradnja za Blazor

Ta navodila razlagajo, kako prevesti OpenSSL za Blazor WebAssembly.


Kaj je WebAssembly?

WebAssembly (WASM) je binarni format, ki teče v brskalniku. Omogoča:

  • Visoko zmogljivo kodo v brskalniku
  • Uporabo jezikov kot C/C++ na spletu
  • Blazor WebAssembly aplikacije

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

Predpogoji

Poleg standardnih orodij potrebujete:

WASM gradnje so možne samo pod Linux/WSL, ne neposredno pod Windows!


Pregled gradnje

WASM gradnja ustvari:

  • openssl.js - JavaScript nalagalnik
  • openssl.wasm - WebAssembly modul
  • C ovoje za Post-Quantum funkcije

Koraki gradnje

Korak 1: Odprite WSL

# Odprite WSL terminal
wsl

Korak 2: Aktivirajte Emscripten

# 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

Korak 3: Priprava imenika za gradnjo

# 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

Korak 4: Konfiguracija OpenSSL za WASM

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

Korak 5: Prevajanje

emmake make -j$(nproc) build_libs

Korak 6: Namestitev

emmake make install_sw

Ustvarjanje JavaScript ovoja

Za integracijo v Blazor potrebujemo ovoj:

wvds_crypto_wrapper.c

// 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);
}

Prevajanje ovoja

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"

Rezultat

Po gradnji:

wasm-build/
├── openssl.js    # JavaScript nalagalnik (~150 KB)
└── openssl.wasm  # WebAssembly modul (~2 MB)

Vključitev v Blazor

1. Kopiranje datotek

cp openssl.js openssl.wasm /mnt/d/MojProjekt/wwwroot/

2. Nalaganje v index.html

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

3. Klic iz Blazor

// 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', [], [])");
}

Popolna skripta za gradnjo

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

Naprej na


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional

Zuletzt geändert: dne 15.12.2025 ob 21:22