Search code examples
node.jsnode-streams

Encrypt file stream and pipe to http response


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.


Solution

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