Hi, it works on some devices but not on all.
In the promise.catch: Set value encountered an error.
got this from logs android studio:
E/SecureStoreModule: java.lang.IllegalStateException: Can't generate certificate
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:137)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.createKeys(SecureStoreModule.java:245)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.getPrivateKey(SecureStoreModule.java:195)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.encryptString(SecureStoreModule.java:122)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.set(SecureStoreModule.java:81)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.setValueWithKeyAsync(SecureStoreModule.java:257)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:363)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:162)
at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
at android.os.Looper.loop(Looper.java:136)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:194)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.UnsupportedOperationException: private exponent cannot be extracted
at com.android.org.conscrypt.OpenSSLRSAPrivateKey.getPrivateExponent(OpenSSLRSAPrivateKey.java:143)
at org.spongycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePrivateKeyParameter(RSAUtil.java:63)
at org.spongycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi.engineInitSign(DigestSignatureSpi.java:95)
at java.security.Signature$SignatureImpl.engineInitSign(Signature.java:631)
at java.security.Signature.initSign(Signature.java:280)
at com.android.org.bouncycastle.x509.X509Util.calculateSignature(X509Util.java:257)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:434)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:412)
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:134)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.createKeys(SecureStoreModule.java:245)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.getPrivateKey(SecureStoreModule.java:195)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.encryptString(SecureStoreModule.java:122)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.set(SecureStoreModule.java:81)
at versioned.host.exp.exponent.modules.api.SecureStoreModule.setValueWithKeyAsync(SecureStoreModule.java:257)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:363)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:162)
at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
at android.os.Looper.loop(Looper.java:136)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:194)
at java.lang.Thread.run(Thread.java:841)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:363)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:162)
at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
at android.os.Looper.loop(Looper.java:136)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:194)
at java.lang.Thread.run(Thread.java:841)
W/System.err: java.lang.IllegalStateException: Can't generate certificate
W/System.err: at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:137)
W/System.err: at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275)
W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.createKeys(SecureStoreModule.java:245)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.getPrivateKey(SecureStoreModule.java:195)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.encryptString(SecureStoreModule.java:122)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.set(SecureStoreModule.java:81)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.setValueWithKeyAsync(SecureStoreModule.java:257)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at java.lang.reflect.Method.invoke(Method.java:515)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:363)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:162)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at android.os.Handler.handleCallback(Handler.java:733)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at android.os.Looper.loop(Looper.java:136)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:194)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at java.lang.Thread.run(Thread.java:841)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: Caused by: java.lang.UnsupportedOperationException: private exponent cannot be extracted
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.android.org.conscrypt.OpenSSLRSAPrivateKey.getPrivateExponent(OpenSSLRSAPrivateKey.java:143)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at org.spongycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePrivateKeyParameter(RSAUtil.java:63)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at org.spongycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi.engineInitSign(DigestSignatureSpi.java:95)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at java.security.Signature$SignatureImpl.engineInitSign(Signature.java:631)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at java.security.Signature.initSign(Signature.java:280)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.android.org.bouncycastle.x509.X509Util.calculateSignature(X509Util.java:257)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:434)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:412)
09-13 16:15:35.371 20631-10786/com.tildepost.mobile W/System.err: at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:134)
@ide that’s strange because i upgraded and have "react-native": "https://github.com/expo/react-native/archive/sdk-21.0.2.tar.gz", in package.json. And did full reinstall of all npm packages. And i followed the upgrade guide for expokit (detached) for v21.
If you’re not using react-native-keychain you may want to remove it, but I think removing it won’t fix your issue since your stack trace includes lines like these, which reference Expo’s SecureStore module:
at javax.crypto.KeyGenerator.getInstance(KeyGenerator.java:135)
10-05 03:18:00.115 14592-18074/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.createSecretKey(SecureStoreModule.java:326)
10-05 03:18:00.115 14592-18074/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.getSecretKeyEntry(SecureStoreModule.java:296)
10-05 03:18:00.115 14592-18074/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.encryptAES(SecureStoreModule.java:155)
10-05 03:18:00.115 14592-18074/com.tildepost.mobile W/System.err: at versioned.host.exp.exponent.modules.api.SecureStoreModule.set(SecureStoreModule.java:109)
We rewrote all that code in SDK 21, though, which is why those stack trace frames must be coming from SDK 20.
@davepack yea i did. @ide, I have .expo-source\android\maven\host\exp\exponent\expoview\21.0.0\expoview-21.0.0-sources.jar in place. I even now copied from new detached project.
Still in the logs i still get old code
We expect this will be addressed in SDK 23. The SecureStore implementation on Android is particularly tricky because different devices and different versions of Android support different crypto providers. This information is available only at runtime and the set of combinations of different crypto configurations is relatively large. We think we have something that works reasonably well but this is one of those APIs that unfortunately needs to be put to test in the wild.
In the meantime you could write a wrapper around SecureStore (call it MaybeSecureStore for example) which tries to use SecureStore and falls back to AsyncStorage if there’s an error.
SDK 22 update — we deployed a new version of the Android standalone app builders that should fix SecureStore for standalone apps on older versions of Android. If SecureStore was working in the Expo client but not in your standalone app for the same version of Android, that issue is likely fixed. We now consistently initialize a crypto library called Spongy Castle in standalone apps so that we get a more predictable set of ciphers for older Android versions.
You will need to rebuild your APK for SDK 22 to get this change. This does not affect a ExpoKit — that enhancement will go out with SDK 23.