Как в node js прочитать опеределенное количество байт из потока?
Пытаюсь зашифровать картинку.
Вкладываю iv вектор в файл
const iv = "Тут рандомные байты"
const read = fs.createReadStream(fileRead);
const write = fs.createWriteStream(fileWrite);
write.write(iv)
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
await stream.pipeline(read, cipher, write);
Все записывает хорошо.
Для расшифровки нужно считать iv (его длинну я знаю) и продолжить расшифровку потока без iv.
Как считать только iv?
stream.read(10) не читает 10 байт, возвращая null;
Ответы (3 шт):
У меня когда-то была похожая задача: удаление BOM из потока перед чтением, и я даже написал тест для этого алгоритма для Node.js. Возможно, он вам поможет:
https://github.com/nodejs/node/commit/ea725eda426add1d684c80f2c2c585cd2ca797c9
Создаём первый readable stream и одним махом читаем первые 100 байт.
Создаём второй readable stream, указывая позицией начала чтения следующий байт.
const fs = require('fs');
const path = require('path');
const { pipeline } = require('stream');
(async () => {
const filepath = path.join(process.cwd(), 'large-file.json');
const stream1 = fs.createReadStream(
filepath,
{
start: 0,
end: 99,
highWaterMark: 100
}
);
const firstByte = await stream1[Symbol.asyncIterator]().next();
console.log(`${filepath} >>> ${firstByte.value}`);
const stream2 = fs.createReadStream(
filepath,
{
start: 100
}
);
await pipeline(stream2, cipher, write);
})();
UPD1: Допустим stream приходит из сторонней библиотеки, как можно считать первые байты, а следующие данные как-то использовать/трансформировать?
const fs = require('fs');
const path = require('path');
(async () => {
const inputfile = path.join(__dirname, 'input.txt');
let iv;
const readStream = fs.createReadStream(inputfile);
readStream.once('readable', () => {
iv = readStream.read(6);
// may be your code here 1
// await pipeline(stream2, cipher, write);
});
// my example
for await (const chunk of readStream) {
console.log(`iv=${iv}, chunk=${chunk}`);
}
// may be your code here 2
})();
iv=123456, chunk=aaaa
iv=123456, chunk=aaaaaaaaaa
iv=123456, chunk=aaafffffff
iv=123456, chunk=gyrtgejeji
iv=123456, chunk=eejiwriuwe
iv=123456, chunk=iweuri'
Решил так:
async _decryptStream(data) {
let writeStream = fs.createWriteStream("test.png");
let iv = "";
ALGORITHM= "aes-256-cbc";
let key = "key";
let decipher;
const test = new stream.Transform({
transform: (chunk, encoding, done) => {
if (!iv) {
iv = chunk.slice(0, 16);
chunk = chunk.slice(16, chunk.length);
decipher = this._getAesDecipher(ALGORITHM, key, iv);
}
done(null, decipher.update(chunk));
},
});
await stream.pipeline(data, test, writeStream);
};