使用Node.js加密文本文件中的各个行

时间:2019-04-22 04:11:36

标签: node.js encryption cryptojs

我正在尝试加密文本文件中的每一行,而不是文本文件本身。这是我用于加密一行文本的代码。

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

2 个答案:

答案 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);
    });