2015-11-05 8 views
6

私のC++アドオンから 'crypto'モジュールに組み込まれたnode.jsを使う必要があります。 ビルドされたモジュールを使用するC++アドオンの例を見つけようとしましたが、失敗しました。 node_crypto.h/.ccを見て、node.js暗号化文書、保護されたコンストラクタなどとは非常に異なる機能シグネチャを持っています。node_crypto.hには1つのパラメータでInitCrypto()宣言が含まれていますが、node_crypto.ccにはそのような機能。 4つのパラメータを持つInitCryptoのみが存在します。私はとにかく、1つのパラメータでInitCryptoを使用しようとしましたが、 "シンボル参照エラー"が発生しました。C++アドオンのモジュールで構築されたnode.jsの使い方

私のアドオンにrequire( 'crypto')の結果を渡して、このオブジェクトで作業することもできますが、これは安全ではありません。 JSコードはクライアントのサーバー上で動作します。

今のところ、C++アドオンが、ノードモジュール 'crypto'の代わりにopenssl libのようなsmthを使う方が簡単だと思います。

私は、Cryptoモジュールを使用しているC++アドオンを使った実例が必要です。これについては、いくつかの記事にリンクしてください。

C++アドオンからビルドされたモジュールを使用している例は役に立ちます。

答えて

6

Nodejsアドオンのデータを暗号化/復号化する必要がある場合と同じ方法を使用しました。

私が理解しているように、node_crypto.hのクラスはNodejでネイティブバインディングを作成するために使用されています。私はそれらをアドオンで使用できませんでした。

次に、NodeSからOpenSSLを使用しようとしましたが、OpenSSLがNodejs実行可能ファイルに静的にリンクされているため、実行できませんでした。その後

私はC++からJavaScriptコードを呼び出して、最終的には、以下のソリューションを持ってしようとした - C++コードからNodejs機能を呼び出すために:

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 
} 

あなたが見ることができるように、V8のAPIとC++のコードが非常に冗長です。実際のプロジェクトでは、v8ppライブラリのユーティリティ関数を使用してオブジェクトプロパティを取得し、V8ハンドルへのデータ変換機能を呼び出しました。

+0

ありがとうございました!このソリューションは、addonにrequire( 'crypto')の結果を渡してより安全です。誰も純粋なC++ソリューションを11月末まで公開しないなら、私はこれを答えにします。誰かがnode_src_root/lib/*。jsファイルに組み込まれているモジュールを修正できることを正しく理解していますか?これらの修正された* .jsファイルはアドオンで使用されますか?パフォーマンステストをしましたか?さて、グローバルオブジェクトにいくつかの関数をキャッシュし、サードパーティの暗号ライブラリと比較しようとしますか? – Dzenly

+1

私は、OpenSSLのようなものを構築することは頭痛になるので、私のアドオンに外部の暗号ライブラリの依存関係を避けるために、これをすばやく汚い方法として使用しました。 はい、この解決策は、ノードソースから 'lib \ *。js'を使用することです。誰かがソースを変更し、この変更されたノードを実行すると、安全でない可能性があります。 アプリケーションの開始時にデータのブロックを1回だけ暗号化/復号化する必要がありました。だから私はこのソリューションのパフォーマンステストをしませんでした。 – pmed

+0

すばらしい解決策! – Icebob

関連する問題