kevlened / isomorphic-webcrypto

:game_die: webcrypto library for Node, React Native and IE11+
https://www.w3.org/TR/WebCryptoAPI/
MIT License
116 stars 42 forks source link

How do I adapt the example in the Usage section to work in React Native? #4

Closed sinewave440hz closed 6 years ago

sinewave440hz commented 6 years ago
import crypto from 'isomorphic-webcrypto'

crypto.subtle.digest(
  { name: 'SHA-256' },
  new Uint8Array([1,2,3]).buffer
)
.then(hash => {
  // do something with the hash buffer
})

This does not work as is in React Native. I have tried the following, but I'm not really sure how to get the values into the digest function. I just want to prove it works as it should.

    const view = new Int8Array( new ArrayBuffer(3));
    crypto.subtle.digest(
      { name: 'SHA-256' },
      view
    )
    .then(hash => {
      // do something with the hash buffer
      console.log('hash: ', hash);
    });

Thanks!

kevlened commented 6 years ago

You'll want an Uint8Array, not an Int8Array. What happens when you pass a Uint8Array instead of a raw buffer?

import crypto from 'isomorphic-webcrypto'

crypto.subtle.digest(
  { name: 'SHA-256' },
  new Uint8Array([1,2,3]) // remove the buffer
)
.then(hash => {
  // do something with the hash buffer
})
kevlened commented 6 years ago

I ask, because I made accommodations to ensure this works.

I was testing using create-react-native-app though, so I'm wondering if something strange is happening when checking instanceof in a different environment.

sinewave440hz commented 6 years ago

Tbh I'm not really sure what the expected outcome should be in this case. In any case, hash is an empty object. Is that correct?

kevlened commented 6 years ago

It should return an ArrayBuffer. If you perform toString() on that you'll get something like ArrayBuffer []. Brief explanation:

An ArrayBuffer is an untyped array that just represents a chunk of memory with a defined length. In order to get a view of that memory, you have to cast it to a typed array. Often, this is a Uint8Array. The U makes it unsigned, so it's alway positive and the 8 makes each element represent one byte.

I imagine what you want is a SHA256 hash as a string. This is most commonly represented in hex. I wrote hex-lite to make this easy, so here's an example:

import crypto from 'isomorphic-webcrypto';
import hex from 'hex-lite';

crypto.subtle.digest(
  { name: 'SHA-256' },
  new Uint8Array([1,2,3]).buffer
)
.then(hash => {
  console.log('sha256 hash', hex.fromBuffer(hash));
});
kevlened commented 6 years ago

I added additional details about hashing to the README. I also included an example of how to generate a hash in the React Native examples.

sinewave440hz commented 6 years ago

(This works fine both on my test app and in your new example app. Thanks.) Now, I'm sitting here expanding on your app just to test all the methods our app currently uses. Would you consider a PR when I'm done on that? (Probably won't be all methods but it might help a bit).

kevlened commented 6 years ago

I'll definitely accept a PR! I'm also curious to see which methods you're using. Just a heads up, I haven't rigorously tested the encryption methods, but digest, signing, verification, and key generation (with a few exceptions) should work.