Web 组装:使用 crypto++ 库与 emscripten

问题描述 投票:0回答:3

我计划将 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

我收到像这样的 wasm-ld 错误 Error screenshots

我做错了什么?我还想公开源代码的其他功能,但我只使用其中一个功能进行测试。

c++ webassembly emscripten crypto++
3个回答
0
投票

我也遇到了同样的问题。 为了让事情变得更简单,我建议您使用 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(您的密钥)


0
投票

从较新版本的 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()

-1
投票

编辑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 代码中设置/获取字符串值的代码,虽然做得不是很好,但感觉你也可以从这方面开始,多亏了它。

让我知道。

© www.soinside.com 2019 - 2024. All rights reserved.