How to use node.js built-in modules from C ++ add-ons

I need to use node.js built into the 'crypto' module from my C ++ addon. I tried to find examples of C ++ add-ons that use built-in modules, but failed. I looked in node_crypto.h / .cc and it has such different function signatures that compare with node.js cryptographic documentation, protected constructors, etc. Node_crypto.h contains an InitCrypto () declaration with one parameter, but node_crypto.cc does not have a definition for such a function. There is only InitCrypto with four parameters. In any case, I tried to use InitCrypto with one parameter and got a "character search error".

I can pass the result of require ('crypto') to my addon and then work with this object, but it is so unsafe. Our JS code runs on the client server.

At the moment, I think it's easier for a C ++ addon to use smth as openssl lib instead of the node 'crypto' built-in module.

So I need some working example with a C ++ addon that uses the 'crypto' module or a link to an article about it.

Any example of using any built-in module from a C ++ add-on will be useful.

+6
source share
1 answer

I used the same when I needed to encrypt / decrypt data in Nodejs addon.

As I understand it, the classes from node_crypto.h are used to create my own bindings in Nodejs, I could not use them in my addon.

Then I tried to use OpenSSL from Nodejs, but could not do it, because OpenSSL is statically linked to the Nodejs executable.

After that, I tried calling JavaScript code from C ++ and finally got the following solution - calling Nodejs functions from C ++ code:

 using namespace v8; // persistent handle for the crypto module static Persistent<Object> node_crypto; // Addon startup procedure void Init(Local<Object> exports, Local<Object> module) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); // get `require` function Local<Function> require = module->Get(String::NewFromUtf8(isolate, "require")).As<Function>(); // call require('crypto') Local<Value> args[] = { String::NewFromUtf8(isolate, "crypto") }; Local<Object> crypto = require->Call(module, 1, args).As<Object>(); // store crypto module in persistent handle for further use node_crypto.Reset(isolate, crypto); } NODE_MODULE(addon, Init); // must be invoked in then Node main thread since the function uses V8 API std::string encrypt(std::string const& key, std::string const& text) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); // get local handle from persistent Local<Object> crypto = Local<Object>::New(isolate, node_crypto); // get `createCipher` function from the crypto module Local<Function> createCipher = crypto->Get(String::NewFromUtf8(isolate, "createCipher")).As<Function>(); // call crypto.createCipher("aes256", key) Local<Value> create_args[] = { String::NewFromUtf8(isolate, "aes256"), String::NewFromUtf8(isolate, key.c_str()) }; Local<Object> cipher = createCipher->Call(crypto, 2, create_args).As<Object>(); // get update and final functions from the crypto module Local<Function> update = cipher->Get(String::NewFromUtf8(isolate, "update")).As<Function>(); Local<Function> final = cipher->Get(String::NewFromUtf8(isolate, "final")).As<Function>(); // buf1 = cipher.update(text), buf2 = cipher.final() Local<Value> update_args[] = { node::Buffer::New(isolate, text.data(), text.size()) }; Local<Value> buf1 = update->Call(cipher, 1, update_args); Local<Value> buf2 = final->Call(cipher, 0, nullptr); // concatenate update and final buffers into result string char const* const data1 = node::Buffer::Data(buf1); char const* const data2 = node::Buffer::Data(buf2); size_t const size1 = node::Buffer::Length(buf1); size_t const size2 = node::Buffer::Lenght(buf2); std::string result; result.reserve(size1 + size2); result.append(data1, size1); result.append(data2, size2); return result; } std::string decrypt(std::string const& key, std::string const& text) { // similar as in encrypt, use createDecipher instead } 

As you can see, the C ++ code with the V8 API is pretty detailed. In a real project, I used the utility functions from my v8pp library to get object properties and call functions with data conversion into V8 handles.

+6
source

All Articles