Ich habe den gleichen Weg verwendet, wenn Daten in einem Nodejs Addon verschlüsselt/entschlüsselt werden mussten.
Wie ich verstehe, Klassen von node_crypto.h
werden verwendet, um native Bindungen in Nodejs, ich konnte sie nicht in meinem Addon verwenden.
Dann habe ich versucht, OpenSSL von Nodejs zu verwenden, konnte es aber nicht, da OpenSSL statisch in die ausführbare Nodejs-Datei eingebunden ist.
Danach habe ich versucht, einen JavaScript-Code von C++ zu nennen und bekam schließlich die folgende Lösung - NodeJS Funktionen von C++ Code aufzurufen:
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
}
Wie Sie sehen können, C++ Code mit V8-API ist ziemlich ausführliche . Im realen Projekt nutzte ich die Funktionen meiner v8pp-Bibliothek, um Objekteigenschaften und Aufruffunktionen mit Datenkonvertierung in V8-Handles zu erhalten.
Vielen Dank! Diese Lösung ist sicherer und übergibt das Ergebnis von require ('crypto') an addon. Wenn niemand bis Ende November pure C++ Lösung posten wird, werde ich dies als Antwort markieren. Verstehe ich richtig, dass jemand eingebaute Module in node_src_root/lib/* .js Dateien korrigieren kann und diese korrigierten * .js Dateien vom Addon benutzt werden? Hast du irgendwelche Leistungstests durchgeführt? Angenommen, Sie versuchen, einige Funktionen in globalen Objekten zwischenzuspeichern und mit Crypto-Bibliotheken von Drittanbietern zu vergleichen. – Dzenly
Ich benutzte dies als einen schnellen und schmutzigen Weg, um eine externe Krypto-Bibliothek-Abhängigkeit in meinem Addon zu vermeiden, weil das Erstellen solcher Sachen wie OpenSSL Kopfschmerzen bereiten würde. Ja, Sie haben Recht, diese Lösung verwendet 'lib \ * .js' aus Knotenquellen. Wenn jemand die Quellen geändert hat und diese modifizierten Nodejs ausführen würde, könnte es unsicher sein. Ich musste einen Datenblock nur einmal beim Start der Anwendung verschlüsseln/entschlüsseln. Daher habe ich für diese Lösung keine Leistungstests durchgeführt. – pmed
Große Lösung! – Icebob