NodeJS exec с двоичным файлом из процесса и для процесса

#javascript #node.js #exec #rsa

#javascript #node.js #exec #rsa

Вопрос:

Я пытаюсь написать функцию, которая использовала бы собственный openssl для выполнения некоторой тяжелой работы с RSA для меня, вместо того, чтобы использовать библиотеку js RSA. Цель состоит в том, чтобы

  1. Чтение двоичных данных из файла
  2. Выполните некоторую обработку в процессе узла, используя JS, в результате чего будет создан буфер, содержащий двоичные данные
  3. Запишите буфер в поток stdin команды exec
  4. RSA шифрует / расшифровывает данные и записывает их в поток стандартного вывода
  5. Возвращает входные данные обратно в буфер в JS-процессе для дальнейшей обработки

У модуля дочернего процесса в Node есть команда exec, но я не вижу, как я могу передать входные данные процессу и передать их обратно в мой процесс. В принципе, я хотел бы выполнить команду следующего типа, но без необходимости полагаться на запись чего-либо в файлы (не проверял точный синтаксис openssl)

 cat the_binary_file.data | openssl -encrypt -inkey key_file.pem -certin > the_output_stream
  

Я мог бы сделать это, написав временный файл, но я хотел бы избежать этого, если возможно. Создание дочернего процесса позволяет мне получить доступ к стандартному интерфейсу / выходу, но я не нашел эту функциональность для exec.

Есть ли чистый способ сделать это так, как я набросал здесь? Есть ли какой-нибудь альтернативный способ использования openssl для этого, например, некоторые собственные привязки для openssl lib, которые позволили бы мне сделать это, не полагаясь на командную строку?

Ответ №1:

Вы упомянули spawn , но, похоже, думаете, что не можете его использовать. Возможно, это показывает мое невежество здесь, но, похоже, это должно быть именно то, что вы ищете: запустите openssl через spawn , затем напишите в child.stdin и прочитайте из child.stdout . Что-то очень примерно похожее на этот полностью непроверенный код:

 var util  = require('util'),
    spawn = require('child_process').spawn;

function sslencrypt(buffer_to_encrypt, callback) {
    var ssl = spawn('openssl', ['-encrypt', '-inkey', ',key_file.pem', '-certin']),
        result = new Buffer(SOME_APPROPRIATE_SIZE),
        resultSize = 0;

    ssl.stdout.on('data', function (data) {
        // Save up the result (or perhaps just call the callback repeatedly
        // with it as it comes, whatever)
        if (data.length   resultSize > result.length) {
            // Too much data, our SOME_APPROPRIATE_SIZE above wasn't big enough
        }
        else {
            // Append to our buffer
            resultSize  = data.length;
            data.copy(result);
        }
    });

    ssl.stderr.on('data', function (data) {
        // Handle error output
    });

    ssl.on('exit', function (code) {
        // Done, trigger your callback (perhaps check `code` here)
        callback(result, resultSize);
    });

    // Write the buffer
    ssl.stdin.write(buffer_to_encrypt);
}
  

Ответ №2:

Вы должны иметь возможность устанавливать двоичную кодировку при вызове exec, например..

 exec("openssl output_something_in_binary", {encoding: 'binary'}, function(err, out, err) {
   //do something with out - which is in the binary format
});
  

Если вы хотите записать содержимое «out» в двоичном формате, убедитесь, что кодировка снова установлена в двоичном формате, например..

 fs.writeFile("out.bin", out, {encoding: 'binary'});
  

Я надеюсь, что это поможет!