Reputation: 39
I'm planning on using the crypto++ library for a web application and wasm seemed perfect for it.
My cpp code:
#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;
}
}
I referred emscripten documentation for using libraries in emscripten I created cryptlib.a using the cryptlib.cpp file and compiled it using emcc like so
emcc -c -o cryptlib.o cryptlib.cpp
ar rcs cryptlib.a cryptlib.o
Finally I also created Source.o like so
emcc -c -o Source.o Source.cpp
I figured out that this would the command to get an html and js file
emcc Source.o cryptlib.a -o source.html -sEXPORTED_FUNCTIONS=_generateKeys -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
I get wasm-ld errors like so Error screenshots
What am I doing wrong? I also want to expose other functions of my source code but I was testing with just one of the functions.
Upvotes: 1
Views: 893
Reputation: 16696
As of newer versions of cryptopp-cmake, this is even more straightforward - if you're using CMake for your own project, the manual steps in the other answer are no longer necessary.
Simply include the following in your project's CMakeLists.txt, to fetch and build cryptopp as part of your emscripten emcmake / emmake build:
include(FetchContent)
FetchContent_Declare(cryptopp-cmake
GIT_REPOSITORY https://github.com/abdes/cryptopp-cmake.git
GIT_TAG CRYPTOPP_8_9_0
)
FetchContent_MakeAvailable(cryptopp-cmake)
Upvotes: 1
Reputation: 779
I was having the same issue. To turn things more easy, i recommend you use CMake to build your project and cryptopp lib for wasm.
1: in your project, create a folder named 3rdparty then:
mkdir 3rdparty
cd 3rdparty
git clone https://github.com/abdes/cryptopp-cmake.git
This is an updated project of crypto++ with cmake
2: After clone the project:
cd cryptopp-cmake
mkdir build
cd build
emcmake cmake -UIS_WASM ../
emmake make
now on your build folder, you will have a folder named: build/_deps (cryptopp include folder) and build/cryptopp/libcrypto.a (cryptopp library)
4: Edit your project CMakeLists.txt for WASM build, here is the mine: Don't forget to change the PROJ_PATH to your project path. I'm building the same version for console version for tests and when i build with emcmake instead cmake it will enter on emscripten condition and load the wasm version of cryptopp lib instead of cryptopp lib on my system for desktop.
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: Finally on your project base path you can run the following commands:
rm -rf build
mkdir build
cd build
emcmake cmake -UIS_WASM ../
emmake make
and on build folder on your project basepath, you will have: RSAPlayground.wasm, RSAPlayground.js and RSAPlayground.data (your keys)
Upvotes: 0
Reputation: 1
EDIT2: That one might be more along what you tried: => https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/samples/basic/js/logic/runAesSymmetricTest.js
=> online sample: ===> https://guillaumebouchetepitech.github.io/wasm-cryptopp-as-module/samples/basic/index.html
it's easier if you map the C++ code with an IDL file: => https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/definitions/wasm-crypto.idl
=> that's one way to make it work: ===> https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/Makefile#L148
something you might want to consider is adding some JS custom logic in the wasm module => https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/src/js/post.js
=> it does need some extra compile flags ===> https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-as-module/blob/main/Makefile#L109
PREVIOUS ANSWER
Looks like you try to use the native version of crypto++, and this will only work if you build the webassembly version of the library.
EDIT: sorry... you were already trying that...
I saw your question here as I was doing it myself. this is what I just published, which might help:
=> wasm online demo:
===> https://guillaumebouchetepitech.github.io/wasm-cryptopp-demo/dist/index.html
=> source code:
===> https://github.com/GuillaumeBouchetEpitech/wasm-cryptopp-demo
PS: I've added the code to set/get string values to/from the js/wasm code as well, it's not overly well done but it feels like you could also get started on that side as well thanks to it.
let me know.
Upvotes: -1