paulmillr/noble-ciphers

Allow replacing crypto.subtle for AES wrappers

shamilovtim opened this issue · 5 comments

The README says that this library supports React Native:

We support all major platforms and runtimes. For Deno, ensure to use npm specifier. For React Native, you may need a polyfill for crypto.getRandomValues.

However, seeing as how the code of this library throws when no crypto.subtle and React Native does not have crypto.subtle, this library does not have RN compat right now.

To support RN package authors have to support node crypto, similar to the other @noble packages which still support node crypto.

The package can be used in react native just fine, specifically, chacha and salsa stuff.

We provide AES wrappers (not full implementation - just wrappers over webcrypto), and those depend on subtle, so you will need a polyfill for it. There are plans to make pure js AES implementation later.

authors have to support node crypto

React Native does not support "node crypto"

We provide AES wrappers (not full implementation - just wrappers over webcrypto), and those depend on subtle, so you will need a polyfill for it.

@paulmillr That's what I was opening the ticket about. There is no React Native subtle.

React Native does not support "node crypto"

All of the existing RN crypto polyfills do in fact use node crypto:

  1. react-native-quick-crypto
  2. crypto-browserify
  3. react native crypto
  4. expo-crypto

None of them support subtle. I'm not counting getRandomValues, since that's only one function.

other @noble packages which still support node crypto.

I've dropped support for node crypto in 4kb secp v2, ed25519 v2. noble-hashes uses node.js webcrypto as you can see here: https://github.com/paulmillr/noble-hashes/blob/main/src/cryptoNode.ts. The reason was because it's not possible to support node crypto if you want ESM modules that work in browsers as-is. You can import secp256k1 in browsers using import * as secp from "url" syntax right now. If there was a call to node.js import, even with if, it would have errored.

With regards to rn polyfills and the fact they don't support subtle - unfortunate, I didn't know this. It complicates things and is shitty.

What you want us to do though? I think there can be a replaceable function like utils.importKey and utils.decrypt that would point to subtle methods by default.

If there was a call to node.js import, even with if, it would have errored.

I didn't know browsers had this problem. That's very unfortunate. I went to test and based on my testing it looks like you can do dynamic imports in browser. Can you check the following MVE: https://github.com/shamilovtim/browser-imports-mve?

Regardless want to make sure you know that in RN we don't error if importing behind an if so you can always handle things that way.

What you want us to do though? I think there can be a replaceable function like utils.importKey and utils.decrypt that would point to subtle methods by default.

That's a good idea. Also I think putting subtle behind an if() would work and also using global.crypto rather than global.crypto.subtle. I'm unfamiliar with the deeper differences between Node crypto and web crypto so I can't speak too much farther on that. In react native imports behind ifs are valid and will avoid errors.