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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (78)

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

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);
    });
提问于
用户回答回答于

首先要实现一个转换流(或利用现有的库)来逐行读取文件。

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'));
用户回答回答于

将所有加密逻辑移动到包括create和end的函数中,然后对文件中的每一行执行此操作。我的问题是尝试重用密码。

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

扫码关注云+社区

领取腾讯云代金券