puleos / object-hash

Generate hashes from javascript objects in node and the browser.
MIT License
1.39k stars 145 forks source link

Support Web Crypto API to enable async hashing #123

Open thernstig opened 1 year ago

thernstig commented 1 year ago

https://nodejs.org/api/webcrypto.html supports async hash functions. Meaning that if this libs implements an async function like:

import hash from 'object-hash';

await hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'

Then users could use async functionality for this.

So the async version should be made clear to depend on Node.js and browsers supporting globalThis.crypto.

strogonoff commented 1 year ago

AFAICT this library relies on Node’s .createHash() exclusively, which is not supported even by browsers supporting globalThis.crypto (nor is it in the Web Crypto spec).

thernstig commented 1 year ago

@strogonoff I am not sure I follow, would something like this not work? The intention is to replace .createHash() with the Web Crypto API.

  const str = "sdomaosdjasjdklasdkjhsdfjkhsdi23894u89weuriuhsduih8i9y893eyu8923hduhdjik3d";
  const encode = new TextEncoder();
  const digest = await webcrypto.subtle.digest('SHA-512', encode.encode(str));
  return Buffer.from(digest).toString('hex');
strogonoff commented 1 year ago

@thernstig Ah yes. I was actually thinking along the same lines, that it’s possible to implement it in a way that works in both Node and browser.

// web version
new Uint8Array(await crypto.subtle.digest('SHA-1', (new TextEncoder()).encode('…'))).toString()
// Node version
new Uint8Array(await require('crypto').webcrypto.subtle.digest('SHA-1', (new TextEncoder()).encode('…'))).toString()

I saw that currently the library relies on Node’s flow, and I guess browserify fills in the gaps so that it works in browser (including browsers that may not support web crypto), that’s what I meant. But yes, it doesn’t have to be that way I guess.

strogonoff commented 1 year ago

(Note that Buffer is a Node-only construct, so an isomorphic solution would probably use Uint8Array instead.)

thernstig commented 1 year ago

Yes. So the main gist of using the Web Crypto API is that it supports await making it async. Second thing is of course that the Web Crypto API is probably the future for Node.js as well.

strogonoff commented 1 year ago

To me the reason for looking into this was not async but clearer and isomorphic logic. Currently there is browserify adding some unnecessary magic and increasing bundle size. Async is a nice bonus though.

ivosabev commented 6 months ago

Are there any plans for this to be released?