我正在尝试加密文本文件中的每一行,而不是文本文件本身。这是我用于加密一行文本的代码。
crypto.pbkdf2(password, salt, iteration, keylen, digest, (error, derivedKey) => {
const iv = Buffer.from('myiv', 'hex');
const cipher = crypto.createCipheriv(algorithm, derivedKey, iv);
let encryptThis = `Encrypt me`;
let encrypted = '';
cipher.on('readable', () => {
let chunk;
while (null !== (chunk = cipher.read())) {
encrypted += chunk.toString('base64');
}
});
cipher.on('end', () => {
console.log(`Example string: ${encryptThis}`);
});
cipher.write(encryptThis);
cipher.end();
});
我知道我也可以使用cipher.update(text)
和cipher.final()
进行加密,并且也很幸运地尝试了此方法。问题是如何逐行读取文件并加密每一行。我已经尝试了两种方法,但是总是导致仅一行被加密或出错。我希望能够通过流转换来做到这一点,就像。
readStream
.pipe(encryptLine)
.pipe(writeStream)
.on('finish', err => {
if (err) console.log(err);
});
答案 0 :(得分:1)
我首先要实现一个转换流(或利用现有的库)以逐行读取文件。
function toLines() {
let line = '';
return new Transform({
decodeStrings: false,
readableObjectMode: true,
transform(chunk, encoding, callback) {
const lines = chunk.split(/\r?\n/g);
line += lines.shift();
while (lines.length) {
this.push(line);
line = lines.shift();
}
callback();
},
flush(callback) {
if (line) {
this.push(line);
}
callback();
}
});
}
然后,我将实现一个转换流以对每一行进行加密。
function encryptLines(algorithm, derivedKey, iv) {
return new Transform({
readableObjectMode: false,
writableObjectMode: true,
transform(line, encoding, callback) {
const cipher = crypto.createCipheriv(algorithm, derivedKey, iv);
this.push(cipher.update(line, encoding, 'base64'));
this.push(cipher.final('base64'));
this.push('\n');
callback();
}
});
}
然后,您可以简单地pipe
将所有内容fs.createReadStream('input.txt', {encoding: 'utf8'})
.pipe(toLines())
.pipe(encryptLines(algorithm, derivedKey, iv))
.pipe(fs.createWriteStream('output.txt'))
.on('finish', () => console.log('done'));
输出到输出流中。
observeForever
答案 1 :(得分:0)
为此找到了解决方案。我将所有加密逻辑移至一个函数,包括创建和结束,并针对文件中的每一行进行了此操作。我的问题是试图重用密码。
const encrypt = (line, thisTransform) => {
crypto.pbkdf2(password, salt, iteration, keylen, digest, (error, derivedKey) => {
const cipher = crypto.createCipheriv(algorithm, derivedKey, iv);
let encrypted = '';
cipher.on('readable', () => {
while (null !== (chunk = cipher.read())) {
encrypted += chunk.toString('base64');
}
});
cipher.on('end', () => {
thisTransform.push(`${encrypted}\n`);
});
cipher.write(line);
cipher.end();
});
};
let encryptLine = new stream.Transform();
encryptLine._transform = function(chunk, encoding, callback) {
let rows = chunk
.toString()
.split('\n')
.map(line => line.replace(/[\n\r]/g, ''))
.forEach(line => {
encrypt(line, this);
});
};
readStream
.pipe(encryptLine)
.pipe(writeStream)
.on('finish', err => {
if (err) console.log(err);
});