上一篇文章分享了基於wasm的openssl實踐,講述了openssl的MD5算法如何在瀏覽器中執行。在探索過程中發現了openssl是可以通過wasm編譯後直接run,並且有自己的runtime,這是因爲openssl.wasm是通過wasmer編譯運行的,這一篇文章分享製作具有運行時的openssl.wasm
概述
- Wasmer介紹
- Openssl編譯到WASM
- 總結
一、Wasmer介紹
Wasmer是一個用於在服務器上執行WebAssembly的開源運行時。支持基於WebAssembly的超輕量級容器,該容器可以在任何地方運行,還可以嵌入其他編程語言。其生態包括以下幾個部分:
1. Wasmer Runtime
Wasmer Runtime是Wasmer生態其中一個,允許wasm模塊可以獨立運行。關鍵功能是使程序能夠以任何編程語言運行;使二進制文件能夠在Wasmer支持的任何“操作系統”(例如Linux、macOS、Windows和FreeBSD)上不加修改地運行;充當Wasm模塊,通過應用程序二進制接口(ABI),如WASI(WebAssembly System Interface)和Emscripten(1.38.43及更早版本)與本機“操作系統”功能交互的安全橋樑。
2. WAPM
WAPM是WebAssembly Package Manager的縮寫,爲可以獨立使用的Wasmer Runtime做的軟件包管理器。可以理解爲通過Wasmer軟件包編譯出來的.wasm文件是可以獨立運行的,WAPM就是爲了管理這些能獨立運行的runtime而存在的。如圖:
搜索一個openssl運行時的.wasm。
提供了運行時環境。
整個看上去和docker hub有點像,還有製作方法,我們可以參考做一個新版的openssl.wasm.
3. WebAssembly.sh
WebAssembly shell程序是一個在線shell程序,您可以在其中拖放WebAssembly模塊以進行嘗試,還可以執行WAPM中可用的WASI模塊的所有命令。在線演示地址:https://webassembly.sh/
4. Wasienv
Wasienv是一個工具,旨在將所有編程語言引入WebAssembly WASI的工具可以將不同的編程語言編譯到WebAssembly中,然後在瀏覽器或服務器中運行程序。
看上去和上一篇我們使用的Emscripten很像,雖然兩者都能把高級語言編譯成.wasm文件,但是後者更注重web方面的開發在瀏覽器中運行(也是第一個生成wasm的工具),前者是解決跨平臺的問題,體現的是wasm的可移植性。
這裏有個WebAssembly WASI的概念,WASI是WebAssembly System Interface的縮寫,是WebAssembly 平臺的系統接口, 由Wasmtime項目設計,目的是爲WASM設計一套引擎無關(engine-indepent), 面向非Web系統(non-Web system-oriented)的API標準。因爲 WebAssembly 是概念機的彙編語言,所以 WebAssembly 需要一個概念操作系統的系統接口,而不是任何單一操作系統的系統接口。 這樣,它就可以在所有不同操作系統中運行。
二、 Openssl編譯到WASM
1. 環境準備
-
Python 3.7.3
-
Pip3 19.3.1
-
Openssl 官網: https://www.openssl.org/source
- 依賴工具 wasienv
2. 安裝wasienv
curl https://raw.githubusercontent.com/wasienv/wasienv/master/install.sh | sh
問題1
我本地無法解析raw.githubusercontent.com
解決辦法
把install.sh複製到本地執行
問題2
執行過程中 pip3 install wasienv --install-option="--install-scripts=$INSTALL_DIRECTORY/bin" --upgrade --user 報錯,不支持這種寫法
WARNING: Skipping wasienv as it is not installed.
/usr/local/lib/python3.7/site-packages/pip/_internal/commands/install.py:235: UserWarning: Disabling all use of wheels due to the use of --build-option / --global-option / --install-option.
cmdoptions.check_install_build_global(options)
ERROR: Location-changing options found in --install-option: ['--install-scripts'] from command line. This is unsupported, use pip-level options like --user, --prefix, --root, and --target instead.
解決辦法
經過查閱資料,是因爲pip3更新到最新版本導致,不支持--install-option=“”顯示傳參,回退版本
pip install --upgrade pip==19.3.1
問題3
執行過程 curl https://get.wasmer.io -sSfL | sh報錯,無法解析域名
解決辦法
瀏覽器訪問,把內容複製出來,我保存的文件是install2.sh,修改install.sh中的引用。
問題4
執行過程 INSTALL_DIRECTORY/bin/wasienv install-sdk unstable
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 659, in urlopen
conn = self._get_conn(timeout=pool_timeout)
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 279, in _get_conn
return conn or self._new_conn()
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 948, in _new_conn
"Can't connect to HTTPS URL because the SSL module is not available."
解決辦法
分析
這是說python沒有ssl模塊,對於依賴的包,無法下載的問題。
經過查閱資料,python ssl模塊對於openssl的版本有要求,所以這裏嘗試升級openssl
# 當前版本
~/Desktop/wasm$ openssl version
LibreSSL 2.8.3
# 安裝其他版本openssl,第一步很慢
brew update && brew upgrade
brew uninstall --ignore-dependencies openssl;
brew install https://github.com/tebelorg/Tump/releases/download/v1.0.0/openssl.rb
參考文檔
https://www.jianshu.com/p/f8585da77ed9
https://stackoverflow.com/questions/45954528/pip-is-configured-with-locations-that-require-tls-ssl-however-the-ssl-module-in/59280089#59280089
https://stackoverflow.com/questions/35280956/ignoring-ensurepip-failure-pip-7-1-2-requires-ssl-tls-python-3-x-os-x#35282183
#設置brew源
https://www.jianshu.com/p/b26c7bc14440
問題4.1
安裝openssl 錯誤
Error: Calling Non-checksummed download of openssl formula file from an arbitrary URL is disabled! Use 'brew extract' or 'brew create' and 'brew tap-new' to create a formula file in a tap on GitHub instead.
If reporting this issue please do so at (not Homebrew/brew or Homebrew/core):
https://github.com/tebelorg/Tump/issues/new
解決辦法
是openssl版本問題
執行
brew uninstall openssl
brew tap-new $USER/old-openssl
brew extract --version=1.0.2t openssl $USER/old-openssl
brew install [email protected]
參考文檔:https://github.com/kelaberetiv/TagUI/issues/635
一頓操作之後,wasienv工具安裝完成。
3. openssl 生成 .wasm文件
我通過WAPM找到了openssl編譯的腳本,這是一個開源的例子。
git clone https://github.com/wapm-packages/OpenSSL.git
目錄結構
build.sh
#!/usr/bin/env sh
# Based on code from https://github.com/TrueBitFoundation/wasm-ports/blob/master/openssl.sh
OPENSSL_VERSION=1.1.1d
PREFIX=`pwd`
DIRECTORY="openssl-${OPENSSL_VERSION}"
if [ ! -d "$DIRECTORY" ]; then
echo "Download source code"
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
tar xf openssl-${OPENSSL_VERSION}.tar.gz
fi
cd openssl-${OPENSSL_VERSION}
echo "Configure"
make clean
wasiconfigure ./Configure linux-x32 -no-asm -static -no-sock -no-afalgeng -DOPENSSL_SYS_NETWARE -DSIG_DFL=0 -DSIG_IGN=0 -DHAVE_FORK=0 -DOPENSSL_NO_AFALGENG=1 -DOPENSSL_NO_SPEED=1 || exit $?
cp ../progs.h apps/progs.h
sed -i 's|^CROSS_COMPILE.*$|CROSS_COMPILE=|g' Makefile
echo "Build"
wasimake make -j12 build_generated libssl.a libcrypto.a apps/openssl
rm -rf ${PREFIX}/include
mkdir -p ${PREFIX}/include
cp -R include/openssl ${PREFIX}/include
cp -R apps/openssl.wasm ../
echo "Done"
思路如下:
- 從openssl官網上下載對應版本的包。
- 通過之前安裝的wasienv工具生成Makefile文件。
- cp progs.h文件到openssl/apps目錄下
- 編譯生成wasm文件,此時wasm文件在apps/openssl目錄下。
- 將openssl/include和.wasm文件複製到新的目錄下。
4、驗證openssl.wasm
~/Desktop/wasm/openssl_demo/OpenSSL$ wasmer run openssl.wasm
OpenSSL> help
Standard commands
asn1parse ca cms crl
crl2pkcs7 dgst dhparam dsa
dsaparam ec ecparam enc
engine errstr exit gendsa
genpkey genrsa help list
nseq ocsp passwd pkcs12
pkcs7 pkcs8 pkey pkeyparam
pkeyutl prime rand rehash
req rsa rsautl sess_id
smime spkac srp ts
verify version x509
Message Digest commands (see the `dgst' command for more details)
blake2b512 blake2s256 gost md4
md5 mdc2 rmd160 sha1
sha224 sha256 sha384 sha512
speed
Cipher commands (see the `enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
aes-256-cbc aes-256-ecb base64 bf
bf-cbc bf-cfb bf-ecb bf-ofb
camellia-128-cbc camellia-128-ecb camellia-192-cbc camellia-192-ecb
camellia-256-cbc camellia-256-ecb cast cast-cbc
cast5-cbc cast5-cfb cast5-ecb cast5-ofb
des des-cbc des-cfb des-ecb
des-ede des-ede-cbc des-ede-cfb des-ede-ofb
des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb
des-ofb des3 desx idea
idea-cbc idea-cfb idea-ecb idea-ofb
rc2 rc2-40-cbc rc2-64-cbc rc2-cbc
rc2-cfb rc2-ecb rc2-ofb rc4
rc4-40 seed seed-cbc seed-cfb
seed-ecb seed-ofb
看起來還不錯,基本的命令還是有的,生成一個rsa私鑰試試。
#!/usr/bin/env sh
wasmer run openssl.wasm --dir=. -- genrsa -des3 -out priv.key 1024 || exit $?
~/Desktop/wasm/openssl_demo/OpenSSL$ cat priv.key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,6D2827691E261E49
ADR7PRPukSBTEHiWvLxuj8DyU9QtiZIC0ZEQxJMRhx7n0b1J5wnrmIMfwbgtVLru
7vi/zdMqwIRJ7Afq3/g0r0/rWA55CF3SCX+UVSGnMrkOV68MWh2ETFCBD3NqmNG3
XZToct1bON0ES6OTEON+4V3PBunSpeU+6EKE8pTOLBeb6Frt1IQ1FgG8xVGfsCnk
DJKncHzN0D66mFlW0mrluiNvHk/PfBvzXQv2FlTdvctThOj/DK6yQ3m4PtPLYn1d
7qOy1wQt1OuXHnymgkR66Rf6OA2aAJXPxBp7C/aVxEAWWLKNw3zv/9rhlOqkIsEQ
i+tnf58VEBR6HGCDXA4UD83x1Pr9h0l5pcrHcvZYv+bnSiIhZGIVSCx0U9jmgbef
qg+L4wzIaaWaOTKpCtHm/10DWII5H6TO6uQHF8Bjz3bvR77tv/jaKRgrG+F7y4h9
5I+DsQjHhcQvIi2aro2o0DGsaD0qLK4jWbvFRxBb7FBfBEFQ9AWz04tZ9Oco5/Ti
ybMaZyLoCNGauqEQV3vS1OoR9IZ1Dzqra5X+YDRSGxTN+31dSCDYH5ta1VTHJyis
SMDfEisqz6vcIyEf+pWzF+yzhQj9aAqFEbWg+pG0Bhx4GXxhLy0WjnFVlWHxjTjN
hoZYC0vKc9uNvzaewFjHEn3IwnXTaXdknE25uBBc18ceBsaW7uzW7D4iPvjhtOC3
znrwo+VGuNPGJTb7md9Dz1q2fjTrPintPftN9ZqxAjeYx+7NiVZfm71mV88EAXYW
eQMQZmTFTiSyTcotDkyRPkvbDbXEytB4sVbwXiBasKxmrgzgz6UIjA==
-----END RSA PRIVATE KEY-----
三、總結
本篇文章主要介紹了WebAssembly的運行時,以及如何製作一個運行時的openssl.wasm。整體感覺還不錯,現在我們有了運行時的openssl.wasm,並且支持基本的命令,但不知道性能如何,下一篇文章分享openssl.wasm與原生openssl性能對比。
參考資料
- Wasmer文檔
- WAPM
Netwarps 由國內資深的雲計算和分佈式技術開發團隊組成,該團隊在金融、電力、通信及互聯網行業有非常豐富的落地經驗。Netwarps 目前在深圳、北京均設立了研發中心,團隊規模30+,其中大部分爲具備十年以上開發經驗的技術人員,分別來自互聯網、金融、雲計算、區塊鏈以及科研機構等專業領域。
Netwarps 專注於安全存儲技術產品的研發與應用,主要產品有去中心化文件系統(DFS)、去中心化計算平臺(DCP),致力於提供基於去中心化網絡技術實現的分佈式存儲和分佈式計算平臺,具有高可用、低功耗和低網絡的技術特點,適用於物聯網、工業互聯網等場景。
公衆號:Netwarps