我计划将 crypto++ 库用于 Web 应用程序,wasm 似乎非常适合它。
我的cpp代码:
#include <string>
using std::string;
#include "cryptopp/cryptlib.h"
#include "cryptopp/rsa.h"
#include "cryptopp/files.h"
#include "cryptopp/osrng.h"
using CryptoPP::RSA;
using CryptoPP::InvertibleRSAFunction;
using CryptoPP::RSAES_OAEP_SHA_Encryptor;
using CryptoPP::RSAES_OAEP_SHA_Decryptor;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::PK_EncryptorFilter;
using CryptoPP::PK_DecryptorFilter;
using CryptoPP::FileSink;
using CryptoPP::FileSource;
using CryptoPP::AutoSeededRandomPool;
using CryptoPP::DecodingResult;
using CryptoPP::SHA1;
using namespace CryptoPP;
extern "C" {
char* generateKeys() {
AutoSeededRandomPool rng;
InvertibleRSAFunction parameters;
parameters.GenerateRandomWithKeySize(rng, 1024);
RSA::PrivateKey privateKey(parameters);
RSA::PublicKey publicKey(parameters);
string pubKey;
publicKey.Save(StringSink(pubKey).Ref());
privateKey.Save(FileSink("privkey.der", true).Ref());
int n = pubKey.length();
char* char_array = new char[n + 1];
strcpy(char_array, pubKey.c_str());
return char_array;
}
}
extern "C" {
char* encrypt(string pubKey, string plain) {
AutoSeededRandomPool rng;
string cipher;
RSA::PublicKey publicKey;
publicKey.Load(StringSource(pubKey, true, NULL).Ref());
RSAES_OAEP_SHA_Encryptor e(publicKey);
StringSource(plain, true,
new PK_EncryptorFilter(rng, e,
new StringSink(cipher)
) // PK_EncryptorFilter
); // StringSource
int n = cipher.length();
char* char_array = new char[n + 1];
strcpy(char_array, cipher.c_str());
return char_array;
}
}
extern "C" {
char* decrypt(const char* filename, string cipher) {
AutoSeededRandomPool rng;
RSA::PrivateKey privateKey;
string recovered;
privateKey.Load(FileSource(filename, true).Ref());
RSAES_OAEP_SHA_Decryptor d(privateKey);
StringSource(cipher, true,
new PK_DecryptorFilter(rng, d,
new StringSink(recovered)
) // PK_EncryptorFilter
); // StringSource
int n = recovered.length();
char* char_array = new char[n + 1];
strcpy(char_array, recovered.c_str());
return char_array;
}
}
我参考了 emscripten documentation 在 emscripten 中使用库 我使用 cryptlib.cpp 文件创建了 cryptlib.a 并使用 emcc 编译它,如下所示
emcc -c -o cryptlib.o cryptlib.cpp
ar rcs cryptlib.a cryptlib.o
最后我也像这样创建了Source.o
emcc -c -o Source.o Source.cpp
我发现这是获取 html 和 js 文件的命令
emcc Source.o cryptlib.a -o source.html -sEXPORTED_FUNCTIONS=_generateKeys -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
我做错了什么?我还想公开源代码的其他功能,但我只使用其中一个功能进行测试。
我也遇到了同样的问题。 为了让事情变得更简单,我建议您使用 CMake 来构建您的项目和 wasm 的 cryptopp 库。
1:在您的项目中,创建一个名为 3rdparty 的文件夹,然后:
mkdir 3rdparty
cd 3rdparty
git clone https://github.com/abdes/cryptopp-cmake.git
这是 crypto++ 使用 cmake 的更新项目
2:克隆项目后:
cd cryptopp-cmake
mkdir build
cd build
emcmake cmake -UIS_WASM ../
emmake make
现在在您的构建文件夹中,您将有一个名为:build/_deps(cryptopp包含文件夹)和build/cryptopp/libcrypto.a(cryptopp库)
的文件夹4:编辑您的项目 CMakeLists.txt 以进行 WASM 构建,这是我的: 不要忘记将 PROJ_PATH 更改为您的项目路径。我正在为控制台版本构建相同的版本进行测试,当我使用 emcmake 而不是 cmake 构建时,它将在 emscripten 条件下进入并在我的桌面系统上加载 wasm 版本的 cryptopp lib 而不是 cryptopp lib。
cmake_minimum_required(VERSION 3.24)
project(RSAPlayground)
set(CMAKE_CXX_STANDARD 17)
set(PROJ_PATH /home/you/your_projects/RSAPlayground) #Change Here
include_directories(/usr/local/include)
add_executable(RSAPlayground main.cpp)
if(${EMSCRIPTEN})
set(EMCC_COMPILER_FLAGS "-g3 -sALLOW_MEMORY_GROWTH=1 -sEXPORTED_FUNCTIONS=_main,_encdec -sEXPORTED_RUNTIME_METHODS=ccall,cwrap --preload-file ${PROJ_PATH}/keys")
set(EMCC_LINKER_FLAGS ${EMCC_COMPILER_FLAGS})
set_target_properties(RSAPlayground PROPERTIES LINK_FLAGS "${EMCC_LINKER_FLAGS}")
#important part:
target_include_directories(RSAPlayground PRIVATE ${PROJ_PATH}/3rdparty/cryptopp-cmake/build/_deps/)
target_link_libraries(RSAPlayground ${PROJ_PATH}/3rdparty/cryptopp-cmake/build/cryptopp/libcryptopp.a)
target_link_libraries(RSAPlayground pthread)
else()
target_include_directories(RSAPlayground PRIVATE /usr/local/include)
target_link_libraries(RSAPlayground /usr/local/lib/libcryptopp.a)
endif()
5:最后,您可以在项目基本路径上运行以下命令:
rm -rf build
mkdir build
cd build
emcmake cmake -UIS_WASM ../
emmake make
在项目基本路径上的构建文件夹中,您将拥有:RSAPlayground.wasm、RSAPlayground.js 和 RSAPlayground.data(您的密钥)
从较新版本的 cryptopp-cmake 开始,这甚至更加简单 - 如果您在自己的项目中使用 CMake,则不再需要其他答案中的手动步骤。
只需在项目的 CMakeLists.txt 中包含以下内容,即可获取并构建 cryptopp 作为 emscripten emcmake / emmake 构建的一部分:
include(FetchContent)
FetchContent_Declare(cryptopp-cmake
GIT_REPOSITORY https://github.com/abdes/cryptopp-cmake.git
GIT_TAG CRYPTOPP_8_9_0
)
FetchContent_GetProperties(cryptopp-cmake)
if(NOT cryptopp-cmake_POPULATED)
FetchContent_Populate(cryptopp-cmake)
add_subdirectory(${cryptopp-cmake_SOURCE_DIR} ${cryptopp-cmake_BINARY_DIR})
endif()
编辑2: 那可能更符合您的尝试: => https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/samples/basic/js/logic/runAesSymmetricTest.js
=> 在线示例: ===> https://guillaumebouchetepitech.github.io/wasm-cryptopp-as-module/samples/basic/index.html
如果将 C++ 代码映射到 IDL 文件会更容易: => https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/definitions/wasm-crypto.idl
=> 这是让它发挥作用的一种方法: ===> https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/Makefile#L148
您可能需要考虑在 wasm 模块中添加一些 JS 自定义逻辑 => https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/src/js/post.js
=> 它确实需要一些额外的编译标志 ===> https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/Makefile#L109
之前的回答
看起来您尝试使用 crypto++ 的本机版本,并且只有在构建库的 WebAssembly 版本时这才有效。
编辑:抱歉...你已经在尝试了...
我在这里看到你的问题,因为我自己也在做。 这是我刚刚发布的内容,可能会有所帮助:
=> wasm 在线演示:
===> https://guillaumebouchetepitech.github.io/wasm-cryptopp-demo/dist/index.html
=>源代码:
===> https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-demo
PS:我还添加了在 js/wasm 代码中设置/获取字符串值的代码,虽然做得不是很好,但感觉你也可以从这方面开始,多亏了它。
让我知道。