question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

"Error storing data" on Android

See original GitHub issue

Hello!

I’m hooking up redux-persist-sensitive-storage in a project. That package relies on react-native-sensitive-info for it to do the actual storage part. On iOS it all seems to be working fine, but on Android (in the simulator at least) I get an error.

Important note: I’m using the keystore branch of of react-native-sensitive-info in order to have encrypted storage on Android. With the package installed through yarn I’m not running into any problems (but then the data is not encrypted).

The error I get is this:

Error storing data Error: null
    at createErrorFromErrorData (NativeModules.js:121)
    at NativeModules.js:78
    at MessageQueue.__invokeCallback (MessageQueue.js:398)
    at MessageQueue.js:137
    at MessageQueue.__guardSafe (MessageQueue.js:314)
    at MessageQueue.invokeCallbackAndReturnFlushedQueue (MessageQueue.js:136)
    at debuggerWorker.js:70

screen shot 2018-08-06 at 13 27 12

My store configuration roughly looks like this:

import { createStore, applyMiddleware, Store } from "redux";
import { persistCombineReducers, PersistConfig, persistStore } from "redux-persist";
import thunk from "redux-thunk";
import createSensitiveStorage from "redux-persist-sensitive-storage";

import reducers from "../reducers";

// redux-persist configuration
const persistConfig: PersistConfig = {
  debug: __DEV__,

  storage: createSensitiveStorage({
    keychainService: "ChaosKeychain",
    sharedPreferencesName: "ChaosSharedPrefs"
  })
};

// Time to create the store
export const store: Store = createStore(
  persistCombineReducers(persistConfig, reducers),
  applyMiddleware(thunk)
);

// ...aaaand, persist it as well
persistStore(store);

Tried to dig a little deeper and have a look at some logs through adb logcat, and I noticed a javax.crypto.IllegalBlockSizeException exception being thrown:

08-06 11:47:44.247  1328  1328 D TrustyKeymaster: Device received get_key_characteristics
08-06 11:47:44.247  1328  1328 E TrustyKeymaster: calling trusty_keymaster_call insize 199 msg size 203
08-06 11:47:44.247  1328  1328 E TrustyKeymaster: Received 158 byte response
08-06 11:47:44.247  1328  1328 D TrustyKeymaster: Device received begin
08-06 11:47:44.247  1328  1328 E TrustyKeymaster: calling trusty_keymaster_call insize 259 msg size 263
08-06 11:47:44.247  1328  1328 E TrustyKeymaster: Received 48 byte response
08-06 11:47:44.249  1328  1328 D TrustyKeymaster: Device received update
08-06 11:47:44.249  1328  1328 E TrustyKeymaster: calling trusty_keymaster_call insize 8908 msg size 8912
08-06 11:47:44.249  1328  1328 E TrustyKeymaster: Received 0 byte response
08-06 11:47:44.249  1328  1328 E TrustyKeymaster: Error deserializing response of size 0
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: javax.crypto.IllegalBlockSizeException
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at javax.crypto.Cipher.doFinal(Cipher.java:1736)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at br.com.classapp.RNSensitiveInfo.RNSensitiveInfoModule.encrypt(RNSensitiveInfoModule.java:255)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at br.com.classapp.RNSensitiveInfo.RNSensitiveInfoModule.putExtra(RNSensitiveInfoModule.java:147)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at br.com.classapp.RNSensitiveInfo.RNSensitiveInfoModule.setItem(RNSensitiveInfoModule.java:90)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at java.lang.reflect.Method.invoke(Native Method)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:160)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.os.Handler.handleCallback(Handler.java:789)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.os.Handler.dispatchMessage(Handler.java:98)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:29)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.os.Looper.loop(Looper.java:164)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:192)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at java.lang.Thread.run(Thread.java:764)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: Caused by: android.security.KeyStoreException: Unknown error
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.security.KeyStore.getKeyStoreException(KeyStore.java:695)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:132)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:217)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
08-06 11:47:44.251  4686  4954 D RNSensitiveInfo: 	... 14 more

When I open up a shell through adb and inspect the shared preferences file that has been generated, I see this:

$ cat AppsharedPrefs.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="persist:AppState">KAysHeVHYPYheW7hRa2xk0qkI+7fCxvNEDYdy4vcwuk2PICGqc+JL2aAajqlFv1FZWxAKkbUxa3a&#10;ThbLmbfK1imgBM55p5IxVtuvMZ4ebsrNi4elnhpAKBsv0LEEgndiIqBXsg6ChcVY8ucNLy5W1fQc&#10;TJ06BlDO2dJKz1o09Q==&#10;    </string>
</map>

So it does look like it has stored information the first time, but if I refresh the app and do something that updates state so it gets persisted, I get the red error screen again.

I’m not sure how to continue with this yet and am hoping that you can help me out with this. Also I’m curious as to whether encrypted storage on Android will be available in the normal package.

Many thanks in advance and if I need to provide additional information then please let me know!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5

github_iconTop GitHub Comments

3reactions
markoudevcommented, Dec 28, 2018

Thanks for the heads-up! Unfortunately, #126 didn’t fix it 😦 I did some more debugging and found that it didn’t happen with little pieces of data. Only when the string to be encrypted was 4073 characters or longer, I would get the IllegalBlockSizeException.

I came across this article: https://proandroiddev.com/security-best-practices-symmetric-encryption-with-aes-in-java-7616beaaade9

And found this piece of text:

Encrypt; if you are encrypting big chunks of data look into CipherInputStream so the whole thing doesn’t need to be loaded to the heap.

The argumentation for using input streams is different, but I thought it would be worth the shot. So I rewrote encryption and decryption using streams and now it seems to be working on Android. You can see my changes here: https://github.com/mCodex/react-native-sensitive-info/compare/keystore...markoudev:keystore

1reaction
Taylor123commented, Jan 16, 2019

@mCodex Any opposition to having @markoudev submit a PR for this? I’ve been experiencing the same problem trying to use the Android keystore and this fix works

Edit: just wanted to note that the intended use case was also for redux state persistence

Read more comments on GitHub >

github_iconTop Results From Across the Web

'Insufficient storage': How to fix that error in Android and iOS
When Android shows the "Insufficient Storage Available" error · Open the Settings app, tap Apps, Applications, or Applications Manager option.
Read more >
[SOLVED] How To Fix Insufficient Storage Available (Android)?
Solution 1: Clear App Cache to Free up Space on Android · Solution 2: Transfer Photos/Videos from Android to Computer · Solution 3:...
Read more >
[FIXED] How To Fix Insufficient Storage Available Error In ...
Use Cloud Storage app to relieve storage space · Remove the unnecessary apps from the device · Use an SD card and transfer...
Read more >
How Fix 'Insufficient Storage' Error: Delete Cached Files in ...
(If you are running Android Marshmallow or later, go to Settings, Apps, select an app, tap Storage and then choose Clear Cache.)
Read more >
Storing and Retrieving the data to the Internal Storage Error ...
Storing and Retrieving the data to the Internal Storage Error ,Android Studio? ; (String FIlename, String datatobeStored) · FileOutputStream fos = ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found