I would like to encrypt a file and serve it as http response on the fly.
My current workflow is this.
const fs = require('fs');
const server = require('http').createServer();
server.on('request', (req, res) => {
const src = fs.createReadStream('./big.file');
src.pipe(res);
});
server.listen(8000);
I would like to encrypt the stream before piping it to the response. I know I have to use tranform stream but I am sure the right implementation for this.
This is well supported in Node.js, there's a section in the crypto documentation on this topic which is very useful: https://nodejs.org/dist/latest-v14.x/docs/api/crypto.html (Example: Using Cipher and piped streams):
const cipher = crypto.createCipheriv(algorithm, key, iv);
const input = fs.createReadStream('test.js');
const output = fs.createWriteStream('test.enc');
input.pipe(cipher).pipe(output);
The above example pipes a file read stream to a file write stream, this is just as easy to pipe to a http response as below:
const crypto = require("crypto");
const fs = require("fs");
// Using 256-bit AES here
const algorithm = "aes-256-cbc";
const key = Buffer.from("22975a65b34aefb6227084727f27bfae234d1be463d1e2f2cc611820e5aa5772", "hex");
const iv = Buffer.from("979843777c873b5a2060c2ad968a20d9", "hex");
const server = require('http').createServer();
server.on('request', (req, res) => {
const cipher = crypto.createCipheriv(algorithm, key, iv);
const src = fs.createReadStream('./big.file');
src.pipe(cipher).pipe(res);
});
server.listen(8000);