themis: [question] [v.0.13.1] [android] getting IncompatibleClassChangeError when trying to bind .aar in C# project [SOLVED by adding ProGuard rules]

Describe the bug

Getting Java.Lang.IncompatibleClassChangeError: no non-static method "Lcom/cossacklabs/themis/SecureCellSeal;.decrypt([B[B)[B" in Release configuration in C# android project. When decrypting “obfuscated” string constant on app start.

Any ideas? Have you seen anything like this in some java or kotlin android project?

To Reproduce

On app start I try to decrypt an “obfuscated” string constant

_secureCell = SecureCell.SealWithKey(masterKeyData);
_secureCell.Decrypt(cipherTextBytes, context);

Getting an error in Release configuration:

Java.Lang.IncompatibleClassChangeError: no non-static method "Lcom/cossacklabs/themis/SecureCellSeal;.decrypt([B[B)[B"
[orion.mobile]   at Java.Interop.JniEnvironment+InstanceMethods.GetMethodID (Java.Interop.JniObjectReference type, System.String name, System.String signature) [0x0005b] in <42d2b7086f0a46efb99253c5db1ecca9>:0 
[orion.mobile]   at Android.Runtime.JNIEnv.GetMethodID (System.IntPtr kls, System.String name, System.String signature) [0x00007] in <3080427739614e60a939a88bf3f838d5>:0 
[orion.mobile]   at Com.Cossacklabs.Themis.SecureCell+ISealInvoker.Decrypt (System.Byte[] p0, System.Byte[] p1) [0x00017] in <cd618986d1ce4194b63cdd3366dad291>:0 
[orion.mobile]   at Themis.Droid.CellSealDroid.UnwrapData (Themis.ISecureCellData cipherTextData, System.Byte[] context) [0x0007e] in <a492e7118e094c3296442a386fe5d80e>:0 
[orion.mobile]    --- End of inner exception stack trace ---

Expected behavior

N/A - this issue is a question

Environment (please complete the following information):

  • OS: Android 10, build 00WW_2_250
  • Hardware: Nokia 7.2
  • Themis version: 0.13.1
  • Installation way:
    • via package manager
    • built from source

Additional context

Sorry for asking in a wrong place if I’m violating any of your policies with this ticket.

I’ve spent a while debugging it and am a bit desperate at the moment. I know you do not support that C# and Xamarin.Forms but filing this question just in case you’ve seen a similar issue in some java or kotlin android project.

Unable to share a sample project

since that does not reproduce on https://github.com/dodikk/themis-xamarin-prototype/tree/bugfix/v0.13.2/droid-strip-symbols Only in a project under NDA, unfortunately.

  • I’ve checked the data I’m getting the failure on. It has been encrypted with wasm-themis CLI tools. Also I can decrypt the data collected from my app’s exception (again, with wasm-themis CLI tools)
  • The same app code and bindings work in debug configuration
  • apk seems to have SecureCellandSecureCellSeal class symbols (checked via “profile apk” UI in android studio) Screenshot 2020-10-06 at 22 46 50

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 25 (5 by maintainers)

Most upvoted comments

Can you please list all the differences between the sample project and the real:

  • the way of Themis installation ==> same. Just downloaded that aar with curl and generated xamarin bindings on top of it. No significant diff between the correspondingcsproj files (C# projects) discovered.
  • usage of same/different Themis API ==> same.
    The C# code of binding/wrapper projects is identical (for “sample” and “real” projects). That code is available in dodikk/themis-xamarin-prototype repository.
  • usage of same/different Themis versions ==> same My “real project” bindings are based on the very same aar binary as the “sample project”.
  • usage of same/different gradle versions, etc? ==> N/A. In my case that was just curl. Copying the same binary on the file system does not help either.

/cc @vixentael

Amazing, really waiting forward!

@vixentael , I have updated develop branch of the demo project. Both the project and readme. https://github.com/dodikk/themis-xamarin-prototype/tree/develop

Will update the default branch of demo repository later, after more testing.

can you add these proguard rules to your sample project? As an illustration.

@vixentael sure. Of course I’ll do that. Also I was planning to document this stuff in the sample’s readme.

Do you accept pull requests to your documentation?

@vixentael , could you please share the URL of the corresponding repo?

As far as I’ve understood so far… Native android devs might run into such issue as well. So documenting this pitfall (in the Installing JavaThemis for Android development) guide might make sense. Unless either

  1. you’ve done so already but I have not noticed that hint
  2. maven or gradle deals with proguard automatically by default
  3. Having the solution documented in this ticket as is good enough

do you think it’s possible to disable it / change optimization level?

@vixentael sure thing it is possible. But I cannot use None since that would bloat the apk size with the entire mono runtime. Which is highly unwanted (ok for debug and in-house; but bad for release and playmarket).

So I need a more fine-tuned fix and can't solve the issue that easily.

Also, xamarin allows specifying manually “which symbols should stay” (see the link below). But I’m viewing that as “weapon of last resort” since that approach would be rather time-consuming (just like writing a makefile without those cmake or autotools helpers). So I’m hoping to find an easier fix and still “on a quest” to find one… https://docs.microsoft.com/en-us/xamarin/cross-platform/deploy-test/linker

[UPD] this docs page of MSDN seems relevant and helpful

I’m trying the guides below to check the “troubles from C# world”

  1. https://gist.github.com/JonDouglas/dda6d8ace7d071b0e8cb
  2. https://www.jon-douglas.com/2017/04/13/linker-bitdiffer/

But no success fo far.

Things start to break when C# apk size optimizer (which they call “linker” for some reason) is set to more aggressive mode (None ==> Sdk Assemblies Only modes mentioned in ). So the high-level hypothesis "the apk size optimizer is stripping too much" looks like the best candidate. On the other hand, the symbols mentioned in the exception are there in the apk

P.S. This comment is not a question but rather an update on “what I’ve discovered so far”

Well, everything is possible, but I don’t think that the toolchain versions matter very much here. We use a standalone toolchain to build it, not Android Studio.

Ok. Then I’ll try other things before applying your toolchain to my app’s build environment. Thanks for providing context, @ilammy

[UPD] a link to cossacklabs/android-build just un case for future readers of this topic https://github.com/cossacklabs/dockerfiles/blob/master/android-build/Dockerfile#L26

Can you try different device / emulator? Please try 64-bit emulator if you’re using x32.

Same results on x64 - Nexus 5 - Android Pie emulator (both for the “real project” and for the prototype; on CipherText data from “real app”) /cc @vixentael

[UPD] same results on Samsung SM-J200H and android v5.1.1 hardware

Can you please use the exact data (encrypted message) that breaks real project to see if it breaks a sample project?

That same data from the “real project” does not break my “sample project”. Checked on the very same nokia device.

/cc @vixentael