jjzjj

node.js - NodeJS 加密 : re-use cipher object to improve performance

coder 2023-11-06 原文

我想要 nodejs 和加密的 MongoDB 数据库。我担心性能。考虑以下用例:

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

因为我很关心性能,所以我做了一些测试来解决这个问题。 我观察到,与加密/解密非常大的字符串相比,加密/解密大量小字符串的速度非常慢。

考虑以下示例:

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");

结果如下:

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

大部分时间花在创建 Cipher 对象上。因此,我想使用相同的密码对象来加密/解密字符串列表。在这种情况下,需要正确处理初始化向量:

  • 如何处理初始化向量?
  • 创建密码对象后,是否可以更改其初始化向量?

理想的场景可能是使用如下伪代码所示的流对象:

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));

最佳答案

您的代码实际上很慢,因为对称算法在离散 block 中工作。

当您加密单个字符串 Your Name 时,密码将用随机字节填充它以达到 block 大小(128 位)的倍数。

因此,您的慢速版本实际上是为每个字符串加密更多数据。

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

关于node.js - NodeJS 加密 : re-use cipher object to improve performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22591733/

有关node.js - NodeJS 加密 : re-use cipher object to improve performance的更多相关文章

随机推荐