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

Error: Failed to read private key

Open elliotsayes opened this issue 3 years ago • 8 comments

Happens intermittently, even though I'm using the same key each time. Seems to happen if I have already called some combination of pbkdf2Sync, createDecipheriv... Will post steps to reproduce at some point.

Exception happens at: https://github.com/margelo/react-native-quick-crypto/blob/main/src/sig.ts#L154 Full trace:

 LOG  [Error: Exception in HostFunction: Failed to read private key

Error: Failed to read private key
    at sign (native)
    at sign (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:167843:37)
    at anonymous (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:124894:76)
    at tryCallTwo (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:61:9)
    at doResolve (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:216:25)
    at Promise (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:82:14)
    at sign (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:124893:27)
    at sign (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:349422:45)
    at ?anon_0_ (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:292308:45)
    at next (native)
    at asyncGeneratorStep (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:25680:26)
    at _next (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:25702:29)
    at tryCallOne (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:53:16)
    at anonymous (/Users/distiller/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:139:27)
    at apply (native)
    at anonymous (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:32266:26)
    at _callTimer (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:32166:17)
    at _callReactNativeMicrotasksPass (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:32201:17)
    at callReactNativeMicrotasks (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:32409:44)
    at __callReactNativeMicrotasks (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:3801:46)
    at anonymous (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:3579:45)
    at __guard (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:3784:15)
    at flushedQueue (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.Evertrove:3578:21)]
info Reloading app...

elliotsayes avatar Oct 20 '22 02:10 elliotsayes

Very confused by this. Inputs to the .sign() function appear to be identical

options input to Sign.sign() :

{"key": "-----BEGIN RSA PRIVATE KEY-----
<A very long RSA key>
-----END RSA PRIVATE KEY-----
", "padding": 6, "saltLength": undefined}

Logging out {data, format, type, passphrase, rsaPadding, pssSaltLength, dsaSigEnc} before calling this.internal.sign(...)

LOG  {"data": [], "dsaSigEnc": 0, "format": 1, "passphrase": undefined, "pssSaltLength": undefined, "rsaPadding": 6, "type": undefined}

These inputs are identical regardless of whether it is successful or not. I can't work out why data would be empty here, or how this.internal consumes the RSA key... very confusing

elliotsayes avatar Oct 20 '22 04:10 elliotsayes

Managed to narrow down the trigger to calling .final() on a Decipher object that has invalid inputs. Doing this will cause any subsequent calls to .sign() on completely unrelated Sign objects to throw an error.

Error is reproduced here: https://github.com/elliotsayes/RnqcRepro - see the Readme for more details

I have no Idea how to approach fixing this, would appreciate any assistance @mrousavy

elliotsayes avatar Oct 21 '22 01:10 elliotsayes

hmm, wdyt @Szymon20000 ?

mrousavy avatar Oct 24 '22 15:10 mrousavy

I found the same issue, as long as I'm providing right passcode when using .decipher I'm able to sign, if I give once invalid passcode, then I need to restart the app because every sign rejects every time with Exception in HostFunction: <unknown>

tobob avatar Jan 16 '23 14:01 tobob

changing CIPHER_ALGORYTHM into RC4-HMAC-MD5 helps

tobob avatar Jan 16 '23 15:01 tobob

it seems like you found a solution, thank you for reporting this problem :)

Montchy avatar Aug 14 '23 09:08 Montchy

I’m sorry what is the solution?

elliotsayes avatar Aug 14 '23 10:08 elliotsayes

@Montchy it seems like the report is legit, and a reproduction was provided. We need to test if we can reproduce using the reproduction. I am going to reopen this ticket.

hannojg avatar Aug 14 '23 15:08 hannojg