简体   繁体   English

Node.js 使用 AES 加密大文件

[英]Node.js encrypts large file using AES

I try to use following code to encrypt a file of 1 GB.我尝试使用以下代码来加密 1 GB 的文件。 But Node.js abort with "FATAL ERROR: JS Allocation failed - process out of memory".但是 Node.js 因“致命错误:JS 分配失败 - 进程内存不足”而中止。 How can I deal with it?我该如何处理?

var fs = require('fs');
var crypto = require('crypto');
var key = "14189dc35ae35e75ff31d7502e245cd9bc7803838fbfd5c773cdcd79b8a28bbd";
var cipher = crypto.createCipher('aes-256-cbc', key);
var file_cipher = "";
var f = fs.ReadStream("test.txt");
f.on('data', function(d) {
    file_cipher = file_cipher + cipher.update(d, 'utf8', 'hex');
});
f.on('end', function() {  
    file_cipher = file_cipher + cipher.final('hex');
});   

You could write the encrypted file back to disk instead of buffering the entire thing in memory:您可以将加密文件写回磁盘,而不是将整个文件缓存在内存中:

var fs = require('fs');
var crypto = require('crypto');

var key = '14189dc35ae35e75ff31d7502e245cd9bc7803838fbfd5c773cdcd79b8a28bbd';
var cipher = crypto.createCipher('aes-256-cbc', key);
var input = fs.createReadStream('test.txt');
var output = fs.createWriteStream('test.txt.enc');

input.pipe(cipher).pipe(output);

output.on('finish', function() {
  console.log('Encrypted file written to disk!');
});

crypto.createCipher() without initialization vector is deprecated since NodeJS v10.0.0 use crypto.createCipheriv() instead.不推荐使用没有初始化向量的crypto.createCipher() ,因为NodeJS v10.0.0使用crypto.createCipheriv()代替。

You can also pipe streams using stream.pipeline() instead of pipe method and then promisify it (so the code will easily fit into promise-like and async/await flow).您还可以使用stream.pipeline()而不是pipe方法来管道流,然后对其进行承诺(因此代码将很容易适应类似 promise 和 async/await 流)。

const {createReadStream, createWriteStream} = require('fs');
const {pipeline} = require('stream');
const {randomBytes, createCipheriv} = require('crypto');
const {promisify} = require('util');

const key = randomBytes(32); // ... replace with your key
const iv = randomBytes(16); // ... replace with your initialization vector

promisify(pipeline)(
        createReadStream('./text.txt'),
        createCipheriv('aes-256-cbc', key, iv),
        createWriteStream('./text.txt.enc')
)
.then(() => {/* ... */})
.catch(err => {/* ... */});

I would simply use the Fileger to do it.我会简单地使用 Fileger 来做到这一点。 It's a promise-based package and a clean alternative to the NodeJS filesystem.它是一个基于 Promise 的包,是 NodeJS 文件系统的干净替代品。

const fileger = require("fileger")
const file = new fileger.File("./your-file-path.txt");

file.encrypt("your-password") // this will encrypt the file
   .then(() => {
      file.decrypt("your-password") // this will decrypt the file
   })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM