Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Unable to decrypt ProviderConfiguration the key used may be invalidated. Please clear data and try again. null #173

Open
ksenia834 opened this issue Jul 24, 2020 · 13 comments

Comments

@ksenia834
Copy link

Describe the bug

During implementation new feature, we've faced few issues, that seems related:

  1. getUserProfile, refreshToken requests return error "Unable to decrypt ProviderConfiguration the key used may be invalidated. Please clear data and try again. null"
  2. Exception on getting accessToken in Release mode: "Unable to decrypt TokenResponse the key used may be invalidated. Please clear data and try again. null". In Debug mode access token received successfully.

It seems similar issue was already reported and closed in 1.0.5 version #113, but for us it still reproduces on 1.0.13

To Reproduce issue 1

  1. Login with Okta user
  2. Get user profile or try refreshToken

Observed Behavior
Error "Unable to decrypt ProviderConfiguration the key used may be invalidated. Please clear data and try again. null" ocured

Expected Behavior
Received User's profile information

To Reproduce issue 2

  1. Login with Okta user
  2. Get accessToken

Observed Behavior
Application crash with exception:

2020-07-24 19:04:51.723 17647-17831/? E/AndroidRuntime: FATAL EXCEPTION: Thread-19
    AuthorizationException: {"type":5,"code":5006,"error":"Illegal block size. Unable to decrypt TokenResponse the key used may be invalidated. Please clear data and try again. null","errorDescription":"Unable to decrypt TokenResponse the key used may be invalidated. Please clear data and try again. null"}
        at com.okta.oidc.util.AuthorizationException$EncryptionErrors.byEncryptionException(Unknown Source:54)
        at com.okta.oidc.clients.sessions.SyncSessionClientImpl.getTokens(Unknown Source:17)
        at com.okta.oidc.clients.sessions.SessionClientImpl.getTokens(Unknown Source:2)
        at com.testapp.Okta.OktaAuthService.refresh(Unknown Source:13)
        at com.testapp.activities.HomeActivity.c(Unknown Source:2)
        at com.testapp.activities.c.run(Unknown Source:2)
        at java.lang.Thread.run(Thread.java:764)

Expected Behavior
User's accessToken (if available) and no crash

Code Snippet

Refresh token:

    sessionClient.refreshToken(object : RequestCallback<Tokens?, AuthorizationException?> {
        override fun onSuccess(result: Tokens) {
            listener?.onTokensRefreshed(result);
        }

        override fun onError(error: String, exception: AuthorizationException?) {
            listener?.onRefreshTokenError(error, exception);
        }
    })

Get user profile:

    sessionClient.getUserProfile(object : RequestCallback<UserInfo, AuthorizationException> {
        override fun onSuccess(result: UserInfo) {
            listener?.onUserProfileReceived(result);

        }

        override fun onError(error: String?, exception: AuthorizationException?) {
            listener?.onUserProfileError(error, exception);
        }
    })

Get access token of successfully signed-in users:

val accessToken = client?.sessionClient?.tokens?.accessToken

Environment

  • SDK Version: com.okta.android:oidc-androidx:1.0.13

Device Information

  • Device: Samsung S8 (Crash reports from Firebase also show Galaxy S10, LG G6, Galaxy A70)
  • OS Version: Android 9 (Crash reports from Firebase also show same issue for Android 10 and Android 8 )
@FeiChen-okta
Copy link
Contributor

Hi @ksenia834 It sounds like release is failing but debug works? Can you send your proguard file?

@bedirguven
Copy link

bedirguven commented Jul 27, 2020

@FeiChen-okta I have the same issue in my project

Environment

  • SDK Version: com.okta.android:oidc-androidx:1.0.14

image

@ksenia834
Copy link
Author

Hi @FeiChen-okta only the exception with token reproduces in Release mode. Method getUserProfile sends error in both Debug and Release modes.

Here the content from proguard.pro:

-ignorewarnings
-keep class * {
    public private *;
}

-keep class yourpackage.** { *; }
-keep class com.shockwave.**
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

here the content from proguard-project.txt:

-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}

# added to prevent runtime errors (kazsato)
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}

-dontwarn android.support.v4.**
-keep class java.lang.reflect.**
-keep class com.android.vending.billing.**
#modify for Facebook
-keepattributes Signature
-keep class com.facebook.model.** { *; }
-keep class com.shockwave.**

-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

Thank you for your help

@FeiChen-okta
Copy link
Contributor

@ksenia834 This doesn't sound like a proguard issue but if you can add -keep class com.okta.oidc.** { *; }.

@bedirguven @ksenia834 Does clearing the cache help?

@ksenia834
Copy link
Author

ksenia834 commented Aug 1, 2020

@FeiChen-okta Thanks for the advice, unfortunately modifying the proguard didn't help.

I've found another step to reach this case:

  1. Login into the app with "remember me"
  2. Remove the app from the device
  3. Install the app again
  4. Check user isAuthenticated:
val session = client?.sessionClient
if (session != null) {
    return session.isAuthenticated
}
  1. If isAuthenticated call refreshToken or try to get the idToken. The call result is error: {"type":5,"code":5006,"error":"Illegal block size. Unable to decrypt ProviderConfiguration the key used may be invalidated. Please clear data and try again. null","errorDescription":"Unable to decrypt ProviderConfiguration the key used may be invalidated. Please clear data and try again. null"}

If try to logout and login again - the token then received correctly.

@FeiChen-okta
Copy link
Contributor

Hi @ksenia834 It looks like your app has allowBackup set to true in AndroidManifest. If you uninstall the app and install again then session.isAuthenticated should return false

If it is returning true then it still have encrypted data from the previous install. The private keys from the previous install is invalidated. No way of recovering that encrypted data so you should clear the data once that error happens.

If you want to allowBackup of your apps data and not the SDK data please refer to the following
https://developer.android.com/guide/topics/data/autobackup#IncludingFiles

@gopalp1709
Copy link

Hi @FeiChen-okta ,I am also getting same exception, in my case I am using bio-metric and refresh token.
It is working fine for first day but on next day it is throwing exception and I am using allowbackup true.
Please suggest how to handle this exception and avoid login again for bio-metric with refresh token.
Thanks
Amol

@FeiChen-okta
Copy link
Contributor

Hi @gopalp1709 Any changes to the device the next day? For example are you adding/removing fingerprint or ping? And what devices is this failing on?

@gopalp1709
Copy link

Hi @FeiChen-okta , I am using following dependencies and Realme XT device (Android 10 ,API 29).
implementation 'com.okta.android:oidc-androidx:1.0.11'
implementation "androidx.browser:browser:1.0.0"

Also I am setting bio-metric by using below function
public void setBiometric() {
try {
EncryptionManager defaultEncryptionManager = ServiceLocator.provideEncryptionManager(MainActivity.this);
defaultEncryptionManager.recreateCipher();
GuardedEncryptionManager guardedBaseEncryptionManager = ServiceLocator.createGuardedEncryptionManager(MainActivity.this);
guardedBaseEncryptionManager.recreateCipher();
getWebAuth().migrateTo(guardedBaseEncryptionManager);
EncryptionManager encryptionManager = guardedBaseEncryptionManager;
ServiceLocator.setEncryptionManager(encryptionManager);
//encryptionManager.recreateCipher();
//mEncryptionManager = guardedBaseEncryptionManager;
} catch (AuthorizationException exception) {
getSessionClient().clear();
navigateToOKTALogin(false);
}
}

And then on biometric success executing these lines:
EncryptionManager encryptionManager = ServiceLocator.provideEncryptionManager(MainActivity.this);
encryptionManager.recreateCipher();

Thanks
Amol

@FeiChen-okta
Copy link
Contributor

Hi @gopalp1709

When is setBiometric method called? It should only be called when the user confirms to use it.
EncryptionManager defaultEncryptionManager = ServiceLocator.provideEncryptionManager(MainActivity.this);
Should be done outside of this method and should have a boolean to see if biometrics was turned on or not.

In the samples it uses a CheckBox to turn on/off biometric and saves this option in sharedprefs.
You should do the following:

  • User successfully logs in, ask the user if they want to enable biometrics.
  • User confirms biometric -> call setBiometric() -> and persist the user's choice in storage.
  • In onCreate check this boolean and create the correct encryption manager from your ServiceLocator. Either createGuardedEncryptionManager or the default one based on the boolean.

@gopalp1709
Copy link

Hi @FeiChen-okta ,
I have verified your suggested steps and I have aligned my code with respect to it. But still I am getting authorization exception as follows :
AuthorizationException: {"type":5,"code":5004,"error":"User not authenticated and try to use private key. User not authenticated and try to decrypt data: User was authenticated 11 seconds ago"}

Above exception occured while fetching getProfile after biometric success.Even my refresh token is not working to get new session unless I clear storage.
Thanks
Amol

@anantrao07
Copy link

Were you able to reach any solution? My scenario is exactly the same as yours @gopalp1709

@satyajitvure91
Copy link

Hey all. I'm also trying to integrate biometric authentication and I'm getting the same issue. sessionClient.isAuthenticated returns true but I'm facing the same issue when trying to get RefreshToken. How to fix this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants