Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

SecureStorage Java.Security.InvalidKeyException: javax.crypto.BadPaddingException #564

Closed
damien-alchemylabz opened this issue Oct 28, 2018 · 5 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@damien-alchemylabz
Copy link

damien-alchemylabz commented Oct 28, 2018

Xamarin Essentials 0.11.0-preview
Android api 22

Description

Had a bit of an issue on a fresh installing on a physical device which i did not have access to. (Samsung api 22)
Had them uninstall and reinstall and then it worked.
I had put this down to secure storage and was able to reproduce on a HUAWEI SCL-L01
From reading the documentation and the fact a reinstall worked i believe its the random key

Steps to Reproduce

  1. android phone api 22
  2. await SecureStorage.SetAsync(key,value);

The documentation states

On older API levels, the Android KeyStore only supports storing RSA keys, which is used with an RSA/ECB/PKCS1Padding cipher to encrypt an AES key (randomly generated at runtime) and stored in the shared preferences file under the key SecureStorageKey, if one has not already been generated.

My workaround

So i believed the system was not happy with the key being generated.
what app starts

1: Test if the SecureStorage.SetAsync is working as expected
If not
2: Set Preferences.Set(SecureStorageKey .... i don't want the random generated one

  /// <summary>
        /// Older api versions will use this key
        /// The autogenerated key from the api is throwing errors so we will set it here
        /// </summary>
        /// <returns>The secure storage preference.</returns>
        public async Task<int> SetSecureStoragePreferenceKey()
        {
            int done = 0;
            try
            {
                //out of interest i want to check what it is now
                var currentSetting = await GetSecureStoragePreferenceKey();

                Preferences.Set("SecureStorageKey", "mysimplesecuritykey");
                done = 1;
            }
             catch (Exception _exp)
            {
                 // handle your error
                done = 0;
            }
            return done;
        }
        /// <summary>
        /// older android api version
        /// </summary>
        /// <returns>The secure storage preference.</returns>
        private async Task<string> GetSecureStoragePreferenceKey()
        {
            string currentValue = string.Empty;
            try
            {
                currentValue = Preferences.Get("SecureStorageKey", "notset");

            }
            catch (Exception _exp)
            {
                // handle your error
                currentValue = "";
            }
            return currentValue;
        }

        /// <summary>
        /// Does the secure storage work as expected on this device
        /// </summary>
        /// <returns>The secure storage.</returns>
        public async Task<bool> TestSecureStorage()
        {
            string testKey = ":testKey";
            string testValue = "testValue";

            bool looksOk = false;
            try
            {
                int s = await SecureStorage_SetAsync(testKey, testValue); // call to SecureStorage.SetAsync(key,value);
                string storedValue = await SecureStorage_GetAsync(testKey);

                looksOk = (storedValue == testValue);
            }
            catch (Exception _exp)
            {
                // handle your error
            }
            return looksOk;
        }

Expected Behaviour

     Set value

Actual Behaviour

Error thrown - exception below

Basic Information

  • Version with issue:
  • Last known good version:
  • IDE:
  • Platform Target Frameworks:
    • Android: API 22 perhaps lower as documented
  • Affected Devices: Known HUAWEI SCL-L01

Exception:

{Java.Security.InvalidKeyException: javax.crypto.BadPaddingException: error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error ---> Javax.Crypto.BadPaddingException: error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error
--- End of inner exception stack trace ---
at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in :0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001f] in :0
at Javax.Crypto.Cipher.Unwrap (System.Byte[] wrappedKey, System.String wrappedKeyAlgorithm, Javax.Crypto.KeyType wrappedKeyType) [0x00059] in :0
at Xamarin.Essentials.AndroidKeyStore.UnwrapKey (System.Byte[] wrappedData, Java.Security.IKey withKey) [0x00012] in C:\bld\Essentials-Release\Xamarin.Essentials\SecureStorage\SecureStorage.android.cs:229
at Xamarin.Essentials.AndroidKeyStore.GetKey () [0x0005c] in C:\bld\Essentials-Release\Xamarin.Essentials\SecureStorage\SecureStorage.android.cs:127
at Xamarin.Essentials.AndroidKeyStore.Encrypt (System.String data) [0x00000] in C:\bld\Essentials-Release\Xamarin.Essentials\SecureStorage\SecureStorage.android.cs:235
at Xamarin.Essentials.SecureStorage.PlatformSetAsync (System.String key, System.String data) [0x00014] in C:\bld\Essentials-Release\Xamarin.Essentials\SecureStorage\SecureStorage.android.cs:48
at Xamarin.Essentials.SecureStorage.SetAsync (System.String key, System.String value) [0x00021] in ...........ServiceManager+<SecureStorage_SetAsync>d__45.MoveNext () [0x00039] in ........cs:77
--- End of managed Java.Security.InvalidKeyException stack trace ---
java.security.InvalidKeyException: javax.crypto.BadPaddingException: error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error
at com.android.org.conscrypt.OpenSSLCipherRSA.engineUnwrap(OpenSSLCipherRSA.java:340)
at javax.crypto.Cipher.unwrap(Cipher.java:1545)
at mono.java.lang.RunnableImplementor.n_run(Native Method)
at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:30)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: javax.crypto.BadPaddingException: error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error
at com.android.org.conscrypt.NativeCrypto.RSA_private_decrypt(Native Method)
at com.android.org.conscrypt.OpenSSLCipherRSA.engineDoFinal(OpenSSLCipherRSA.java:273)
at com.android.org.conscrypt.OpenSSLCipherRSA.engineUnwrap(OpenSSLCipherRSA.java:325)
... 11 more

@jamesmontemagno jamesmontemagno added the bug Something isn't working label Oct 30, 2018
@jamesmontemagno jamesmontemagno added this to the 0.12.0-preview milestone Oct 30, 2018
@Redth
Copy link
Member

Redth commented Nov 2, 2018

So this is randomly not working correctly?

@Mikilll94
Copy link

Mikilll94 commented Nov 2, 2018

I had this error some time ago. I think this is caused if the user has enabled backing up data from the app on Google Drive and restoring it during reinstallation of the app.

I solved this problem by specifing that I don't want to backup and restore any data from my app on Google Drive. This can be done easily in Android manifest like this:

<manifest ... >
    ...
    <application android:allowBackup="false" ... >
        ...
    </application>
</manifest> 

Source: https://developer.android.com/guide/topics/data/autobackup

However, Google recommends separating data which you want to backup and sensitive data which you don't. Data allowed for backup SHOULD NOT be stored in Secure Storage because the symmetric key is changing after every launch of the app, so it can throw the exception from this issue if data is encrypted with an outdated symmetric key.

You can read more about that on Android documentation about Autobackup.

I hope it helps :)

@damien-alchemylabz
Copy link
Author

I don't want to say randomly but above is the best guess i have. I've been wrong before :)

AES key (randomly generated at runtime) and stored in the shared preferences file under the key SecureStorageKey

Yesterday i tried fresh installs (x4) on the same device to attempt a re-create but it didn't happen.
(It worked without disabling the backup in above post so as unable to test that)

Ill be able to to test a brand new install in the coming days (new app) and see if happens again.

@jamesmontemagno jamesmontemagno modified the milestones: 0.12.0-preview, 1.0.0 Nov 5, 2018
@jamesmontemagno
Copy link
Collaborator

Linked to #602

For this if we see an exception occur we will blow away all secure storage keys and re-generate things.

I recommend setting up the selective backup; https://docs.microsoft.com/en-us/xamarin/essentials/secure-storage?tabs=android

mattleibow added a commit that referenced this issue Nov 5, 2018
@mattleibow
Copy link
Contributor

Changes merged.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants