我想要 nodejs 和加密的 MongoDB 数据库。我担心性能。考虑以下用例:
因为我很关心性能,所以我做了一些测试来解决这个问题。 我观察到,与加密/解密非常大的字符串相比,加密/解密大量小字符串的速度非常慢。
考虑以下示例:
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");
结果如下:
大部分时间花在创建 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/