NodeJSencryption:重新使用密码对象来提高性能

我想要nodejs和一个encryption的MongoDB数据库。 我担心表演。 考虑下面的用例:

  1. 我有一个encryption的数据库,我从中检索encryptionstring列表(例如名称)[_encrypted_name_1,_encrypted_name_2,…]
  2. 我想解密列表中的所有元素

由于我担心表演,所以我做了一些testing来搞清楚。 我观察到,encryption/解密很多小string比encryption/解密一个非常大的string要慢很多。

考虑下面的例子:

var crypto = require('crypto'), _ = require('lodash'), encryptedStringArray = [], decryptedStringArray = [], encryptedLongString, NB_ITERATION = 100000, stringArray = [], longString = '', myString = 'Your Name'; function encrypt(text){ var cipher = crypto.createCipher('aes-256-cbc', 'd6F3Efeq'); var crypted = cipher.update(text, 'utf8', 'hex'); crypted += cipher.final('hex'); return crypted; } function decrypt(text){ var decipher = crypto.createDecipher('aes-256-cbc', 'd6F3Efeq'); var dec = decipher.update(text, 'hex', 'utf8'); dec += decipher.final('utf8'); return dec; } // SLOW: ARRAY OF STRINGS console.time("slow"); for (var i = 0; i < NB_ITERATION; i += 1) { stringArray.push(myString); } _.forEach(stringArray, function (item) { encryptedStringArray.push(encrypt(item)); }); _.forEach(encryptedStringArray, function (item) { decryptedStringArray.push(decrypt(item)); //.toString()); }); console.timeEnd("slow"); // FAST: SUPER LONG STRING console.time("fast"); for (var i = 0; i < NB_ITERATION; i += 1) { longString += myString; } encryptedLongString = encrypt(longString); decrypt(encryptedLongString); console.timeEnd("fast"); // ********************************************************************** // FOR LOOP // ********************************************************************** // console.time("for_loop"); stringArray = []; encryptedStringArray = []; decryptedStringArray = []; for (var i = 0; i < NB_ITERATION; i += 1) { stringArray.push(myString); } _.forEach(stringArray, function (item) { encryptedStringArray.push(myString); }); _.forEach(encryptedStringArray, function (item) { decryptedStringArray.push(myString); }); console.timeEnd("for_loop"); // ********************************************************************** // CREATION OF CIPHER ONLY - NO ENCRYPTION // ********************************************************************** function noencrypt(text){ var cipher = crypto.createCipher('aes-256-cbc', 'd6F3Efeq'); // var crypted = cipher.update(text, 'utf8', 'hex'); // crypted += cipher.final('hex'); // return crypted; return text; } function nodecrypt(text){ var decipher = crypto.createDecipher('aes-256-cbc', 'd6F3Efeq'); // var dec = decipher.update(text, 'hex', 'utf8'); // dec += decipher.final('utf8'); // return dec; return text; } // SLOW console.time("slow_nocrypt"); for (var i = 0; i < NB_ITERATION; i += 1) { stringArray.push(myString); } _.forEach(stringArray, function (item) { encryptedStringArray.push(noencrypt(item)); }); _.forEach(encryptedStringArray, function (item) { decryptedStringArray.push(nodecrypt(item)); //.toString()); }); console.timeEnd("slow_nocrypt"); // FAST console.time("fast_nocrypt"); for (var i = 0; i < NB_ITERATION; i += 1) { longString += myString; } encryptedLongString = noencrypt(longString); nodecrypt(encryptedLongString); console.timeEnd("fast_nocrypt"); 

结果如下:

  • 慢:2078ms
  • 快:20ms
  • for_loop:14ms
  • slow_nocrypt:1898ms
  • fast_nocrypt:1ms

大部分时间用于创build密码对象。 因此,我想使用相同的密码对象来encryption/解密string列表。 在这种情况下,需要正确处理初始化向量:

  • 如何处理初始化向量?
  • 一旦密码对象被创build,是否有可能改变它的初始化向量?

理想的情况可能是使用以下伪代码所示的stream对象:

 var myArray = [ {to_encrypt: 'Your Name 1', iv: INIT_VECTOR_1}, {to_encrypt: 'Your Name 2', iv: INIT_VECTOR_2}]; var encrypted_array = []; streamify(myArray) .pipe(CIPHER_WITH_IV_UPDATE) .write(streamify(encrypted_array)); 

你的代码实际上很慢,因为对称algorithm在离散块中工作。

encryption单个stringYour Name ,密码将用随机字节填充以达到块大小(128位)的倍数。

因此,你的慢版本实际上是每个stringencryption更多的数据。

要加快速度,请使用较小的块大小或每块encryption更多的数据。