react-native-quick-crypto icon indicating copy to clipboard operation
react-native-quick-crypto copied to clipboard

🐛 Key must be one of type CryptoKey, KeyObject, or Uint8Array error when using jose with react-native-quick-crypto

Open freiserg opened this issue 8 months ago • 8 comments

What's happening?

When using react-native-quick-crypto together with the jose library in a React Native app, calling exportJWK() throws the following error:

TypeError: Key must be one of type CryptoKey, KeyObject, or Uint8Array. Received an instance of CryptoKey

Reproducible Code

const { publicKey, privateKey } = await generateKeyPair('ES256', { extractable: true });

const publicKeyJwk = await exportJWK(publicKey);

Relevant log output

TypeError: Key must be one of type CryptoKey, KeyObject, or Uint8Array. Received an instance of CryptoKey

Device

iPhone 16

QuickCrypto Version

0.7.13

Can you reproduce this issue in the QuickCrypto Example app?

I didn't try (⚠️ your issue might get ignored & closed if you don't try this)

Additional information

freiserg avatar Apr 22 '25 10:04 freiserg

react-native-quick-crypto CryptoKey instances are missing its Symbol.toStringTag and so this fails. Filling in the the tag should help.

panva avatar Apr 26 '25 08:04 panva

@panva hi 👋

I attempted to add the Symbol.toStringTag values for the RNQC classes, and add tests in this commit. Any idea why I'd be seeing the following?

fail: importJwk - error: Cannot read property 'slice' of undefined
fail: exportJWK - error: Invalid argument - options.modulusLength is not a number: undefined

Is the first one just a bad JWK, missing some key/value?

Is the second one missing some options?

Thought I'd take a quick stab at this.

boorad avatar May 09 '25 18:05 boorad

@boorad do you have a full error trace and code you're executing for these?

panva avatar May 09 '25 18:05 panva

It's a liitle wack, because RN:

TypeError: Cannot read property 'slice' of undefined
    at getHashLength (http://localhost:8081/index.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&excludeSource=true&sourcePaths=url-server&app=com.margelo.rnqc.example.RNQCExample:153197:36)
    at checkEncCryptoKey (http://localhost:8081/index.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&excludeSource=true&sourcePaths=url-server&app=com.margelo.rnqc.example.RNQCExample:153314:39)
    at ?anon_0_ (http://localhost:8081/index.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&excludeSource=true&sourcePaths=url-server&app=com.margelo.rnqc.example.RNQCExample:153770:79)
    at next (native)

I made a change, and got past the `options.modulusLength issue. Back to the OG error message:

TypeError: Key must be one of type CryptoKey, KeyObject, or Uint8Array.
    at ?anon_0_ (http://localhost:8081/index.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&excludeSource=true&sourcePaths=url-server&app=com.margelo.rnqc.example.RNQCExample:154268:28)
    at next (native)
...
    at keyToJWK (http://localhost:8081/index.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&excludeSource=true&sourcePaths=url-server&app=com.margelo.rnqc.example.RNQCExample:154248:27)
    at ?anon_0_ (http://localhost:8081/index.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&excludeSource=true&sourcePaths=url-server&app=com.margelo.rnqc.example.RNQCExample:154232:38)
    at next (native)
...
    at exportJWK 
...

boorad avatar May 09 '25 18:05 boorad

@panva code pushed, stacks above ^

boorad avatar May 09 '25 18:05 boorad

TypeError: Cannot read property 'slice' of undefined at getHashLength

The algorithm member of the key is missing required property for its given type. In this case, RsaHashedKeyAlgorithm missing its hash property which itself is supposed to be a KeyAlgorithm dictionary.

panva avatar May 09 '25 18:05 panva

Invalid argument - options.modulusLength is not a number: undefined

I am not sure where this is coming from.

Edit:

that's a bad call you're doing to node:crypto generateKeyPair here

    crypto.generateKeyPair('rsa', {} /* <- missing modulusLength */, (err, publicKey) => {
      if (err) {
        throw err;
      }
      const publicKeyJwk = exportJWK(publicKey as CryptoKey);
      console.log(publicKeyJwk);
    });

Also the result of this is a KeyObject, not CryptoKey.

panva avatar May 09 '25 18:05 panva

I made a change, and got past the `options.modulusLength issue. Back to the OG error message:

It's likely you're returning a symbol string tag values PublicKeyObject, PrivateKeyObject, AsymmetricKeyObject, or SecretKeyObject instead of just KeyObject which is what Node.js is doing for all these subclasses.

panva avatar May 09 '25 19:05 panva

any update on this?

ahkela21 avatar Nov 08 '25 15:11 ahkela21