react-native-keychain: Unknown error: Could not encrypt value for service RN_KEYCHAIN_DEFAULT_ALIAS, message: javax.crypto.IllegalBlockSizeException

RNKeychainManager: Unknown error: Could not encrypt value for service RN_KEYCHAIN_DEFAULT_ALIAS, message: javax.crypto.IllegalBlockSizeException

I was getting this when password/value content got bigger, but a content shortening/downsizing made the error “disappear”.When the content size is about 9000 bytes, it will not be stored.

react-native-keychain:3.1.3, compileSdkVersion 28 buildToolsVersion ‘27.0.3’

In debug mode, I found that the error location is the code in the “CipherStorageKeystoreAESCBC.java” file: private byte[] encryptString(Key key, String service, String value) throws CryptoFailedException { try { Cipher cipher = Cipher.getInstance(ENCRYPTION_TRANSFORMATION); cipher.init(Cipher.ENCRYPT_MODE, key); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // write initialization vector to the beginning of the stream byte[] iv = cipher.getIV(); outputStream.write(iv, 0, iv.length); // encrypt the value using a CipherOutputStream CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher); cipherOutputStream.write(value.getBytes("UTF-8")); cipherOutputStream.close(); return outputStream.toByteArray(); } catch (Exception e) { throw new CryptoFailedException("Could not encrypt value for service " + service + ", message: " + e.getMessage(), e); } } Throw this exception when “cipherOutputStream.close()” I need help…

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 11
  • Comments: 19

Commits related to this issue

Most upvoted comments

I’m also getting this error when trying to setGenericPassword using RSA as the storage type (AES and FB doesn’t throw it). It also happens if I don’t set the storage type but set the accessControl to use biometrics (which I assume sets RSA as the storage type by default as well).

I’m using the latest 6.0.0 version.

@sebk: Thank you for the feedback. I was finally able to get this to work for me…but, not real happy with the solution. Essentially, I split the token into multiple parts (as you suggested). In order to get the biometrics to work (only fire once), I stored the shortest part of the token in RSA, with all other parts stored in AES. Obviously, I had to rebuild the token upon retrieval. It is a bit of a pain and a little clunky, but it does work…just not as seamless on Android, as it is on iOS.

Thanks @markrickert for your comment, can you share some code so we don’t have to reinvent the wheel? or if you just used any useful existing js lib for chunking and unchunking that would be very much appreciated 👌🏼 not to code that 🤮 boilerplate stuff 🤣

I’m getting this issue on the latest release (4.0.5)

@rgreen33 : “For some reason, long strings are being corrupted.” => This reminds me of https://github.com/oblador/react-native-keychain/issues/184. The solution in this issue was to split the token in multiple parts and save these parts separately. I also used the “splitting token” solution and it worked well. I didn’t tested every library release to see if this error was fixed. With some later release (can’t remember which one) the error still exists and I never removed this splitting solution from my code (actually I’m not using this library anymore, sorry - no offence).

But I would guess that this is another problem?

I have also the same problem/error (Illegal Block Size) on e.g. a Pixel 3 and I’m unable to use RSA anymore. The error sounds like this issue: https://security.stackexchange.com/a/33445, but I’m not sure.

Sorry when everything I mentioned is nonsense. 😃

I was able to find a workaround using the following settings:

export const saveCookie = (user: string, cookie: Cookie) => {
  return Keychain.setInternetCredentials(
    SERVER_COOKIE,
    user,
    JSON.stringify(cookie),
    {
      rules: Keychain.SECURITY_RULES.NONE,
      storage: Keychain.STORAGE_TYPE.AES,
      accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
    },
  ).catch((error) => console.log(`Error saving cookie to storage: ${error}`));
};

@rgreen33

Has anyone been able to get past this issue on Android? If so, could you share how you did it?