Incorrect NodeJS Crypto Hash when using ReadableStream.pipe

59 views Asked by At

I tried calculate the sha256 hash in 2 different ways, only one of which gave the correct result.

import { createHash } from 'node:crypto';
import { Readable } from 'node:stream';

function f1(info: NodeJS.ReadableStream) {
  return new Promise((resolve, reject) => {
    const hash = createHash('sha256');

    info.on('data', (data) => hash.update(data));
    info.on('end', () => resolve(hash.digest('hex')));
    info.on('error', (error) => reject(error));
  });
}

function f2(info: NodeJS.ReadableStream){
  const hasher = createHash('sha256');
  return info.pipe(hasher).digest('hex');
}

export async function test() {
  const h1 = await f1(Readable.from('Testing'));
  const h2 = f2(Readable.from('Testing'));

  console.log(h1);
  console.log(h2);
}

test();

Output:

e806a291cfc3e61f83b98d344ee57e3e8933cccece4fb45e1481f1f560e70eb1
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Only f1 gave the correct hash. Is there anyone with the clue to why it is so?

1

There are 1 answers

1
spjdev On BEST ANSWER

f1 and f2 are process data streams differently. For the f2 you can't use the digest with the pipe. The pipe returns a writable steam I think. Try this:

function f2(info: NodeJS.ReadableStream) {
  const hasher = createHash('sha256');
  return new Promise((resolve, reject) => {
    info.pipe(hasher)
      .on('finish', () => resolve(hasher.digest('hex')))
      .on('error', (error) => reject(error));
  });
}