terl / lazysodium-android

An Android implementation of the Libsodium cryptography library. For the lazy dev.
https://github.com/terl/lazysodium-java/wiki
Mozilla Public License 2.0
108 stars 25 forks source link

Base64 import error in Android SDK version below 27 #58

Closed MobatiaArshad closed 2 years ago

MobatiaArshad commented 2 years ago

Fatal Exception: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;

Crash reports are occurring in the lower SDK versions like (22,23,24,25) which leads to the java Base64

Fatal Exception: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/Base64;
       at com.goterl.lazysodium.utils.Key.fromBase64String(Key.java:55)
       at com.myrxprofile.rxprofile.widgets.encode.EncryptionCenter.getServerPublicKey(EncryptionCenter.kt:148)
       at com.myrxprofile.rxprofile.widgets.encode.EncryptionCenter.decryptMessage(EncryptionCenter.kt:97)
       at com.myrxprofile.rxprofile.view.login.LoginRepository.decryptData(LoginRepository.kt:17)
       at com.myrxprofile.rxprofile.view.login.LoginViewModel$loginTesting$1.onResponse(LoginViewModel.kt:72)
       at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$retrofit2-DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
       at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$$ExternalSyntheticLambda0.run(D8$$SyntheticClass)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

also File no found eception in the DexPathList

Caused by java.lang.ClassNotFoundException: Didn't find class "java.util.Base64" on path: DexPathList[[zip file "/data/app/com.myrxprofile.rxprofile-2/base.apk"],nativeLibraryDirectories=[/data/app/com.myrxprofile.rxprofile-2/lib/x86, /data/app/com.myrxprofile.rxprofile-2/base.apk!/lib/x86, /vendor/lib, /system/lib]]
       at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
       at com.goterl.lazysodium.utils.Key.fromBase64String(Key.java:55)
       at com.myrxprofile.rxprofile.widgets.encode.EncryptionCenter.getServerPublicKey(EncryptionCenter.kt:148)
       at com.myrxprofile.rxprofile.widgets.encode.EncryptionCenter.decryptMessage(EncryptionCenter.kt:97)
       at com.myrxprofile.rxprofile.view.login.LoginRepository.decryptData(LoginRepository.kt:17)
       at com.myrxprofile.rxprofile.view.login.LoginViewModel$loginTesting$1.onResponse(LoginViewModel.kt:72)
       at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$retrofit2-DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
       at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$$ExternalSyntheticLambda0.run(D8$$SyntheticClass)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

I have searched about the issue and what I figured is current Base64 is imported from the java.util but is must be imported from android.util.

This is how I decrypt the Base64 in my code

 private fun getServerPublicKey(): Key? {
        return Key.fromBase64String(SERVERPUBLICKEY)
    }

But the Key class imports the Base64 from the java.util

image

Please let me know if am calling the function right method

gurpreet- commented 2 years ago

Hi @MobatiaArshad,

I have updated the lib to handle this.

  1. If your program automatically creates an instance of LazySodiumAndroid using its constructors e.g new LazySodiumAndroid() then you can use fromBase64String(String) as normal.
  2. Or you can set Sodium.base64Facade to Base64Android() at the start of your program's execution then you use fromBase64String(String) as normal.
  3. Or pass in Base64Android into the following new function fromBase64String(String, Base64Facade) wherever you need it.

I haven't yet released version 5.1.1 of the lib yet so you can test this in a snapshot build: 5.1.1-SNAPSHOT.

MobatiaArshad commented 2 years ago

Thanks for the update @gurpreet- ❤

dpalou commented 1 year ago

Hi @gurpreet- , we're also affected by this issue and it's currently blocking the new release of our app. Can you please give more details about how to use 5.1.1-SNAPSHOT?

It's a Cordova app, and in the plugin.xml of one of our Cordova plugins I added the dependency like this:

<framework src="com.goterl:lazysodium-android:5.1.1-SNAPSHOT@aar"/>

But I get the following error when compiling:

Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not find com.goterl:lazysodium-android:5.1.1-SNAPSHOT.
     Searched in the following locations:
       - https://dl.google.com/dl/android/maven2/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/maven-metadata.xml
       - https://dl.google.com/dl/android/maven2/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/lazysodium-android-5.1.1-SNAPSHOT.pom
       - https://repo.maven.apache.org/maven2/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/maven-metadata.xml
       - https://repo.maven.apache.org/maven2/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/lazysodium-android-5.1.1-SNAPSHOT.pom
       - https://jcenter.bintray.com/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/maven-metadata.xml
       - https://jcenter.bintray.com/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/lazysodium-android-5.1.1-SNAPSHOT.pom
       - https://maven.google.com/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/maven-metadata.xml
       - https://maven.google.com/com/goterl/lazysodium-android/5.1.1-SNAPSHOT/lazysodium-android-5.1.1-SNAPSHOT.pom
     Required by:
         project :app

This works fine when using 5.1.0, do I need to change anything to be able to use a snapshot in our app?