patrickfav / armadillo

A shared preference implementation for confidential data in Android. Per default uses AES-GCM, BCrypt and HKDF as cryptographic primitives. Uses the concept of device fingerprinting combined with optional user provided passwords and strong password hashes.
https://favr.dev/opensource/armadillo
Apache License 2.0
280 stars 52 forks source link

Migrate to AndroidX #30

Closed davidmigloz closed 4 years ago

davidmigloz commented 6 years ago

I was trying to migrate the library to AndroidX, but I'm having problems with the bcrypt library.

When I try to compile I get:

SecurityException: SHA-256 digest error for at/favre/lib/crypto/bcrypt/BCryptFormatter.class

My guess is that Jetifier is trying to modify the bcrypt library jar (although I don't know why, because it doesn't have any android support dependency). But the library is signed with your private key, so then the signature validation fails.

@patrickfav do you have any clue how can we solve the issue?

davidmigloz commented 6 years ago

I found the issue.. it was Instant Run the one that was causing the error. I just disabled it and works fine.. I'll tidy the code a bit and complete the pr.

davidmigloz commented 6 years ago

I've finished the migration to AndroidX. I've also extracted the dependencies to a separate file to have them more organised. Take a look when you have time 😄

davidmigloz commented 6 years ago

testReleaseUnitTest task is failing with the same error I was getting with Instant Run at the beggining:

at.favre.lib.armadillo.AuthenticatedEncryptionTest > encryptMultiple FAILED
    java.lang.SecurityException: SHA-256 digest error for at/favre/lib/bytes/Bytes.class
        at sun.security.util.ManifestEntryVerifier.verify(ManifestEntryVerifier.java:223)
        at java.util.jar.JarVerifier.processEntry(JarVerifier.java:243)
        at java.util.jar.JarVerifier.update(JarVerifier.java:230)
        at java.util.jar.JarVerifier$VerifierStream.read(JarVerifier.java:484)
        at sun.misc.Resource.getBytes(Resource.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:462)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at at.favre.lib.armadillo.AuthenticatedEncryptionTest.encryptMultiple(AuthenticatedEncryptionTest.java:35)

I was also getting the same error in my production app in combination with Firebase Performance Monitoring library (sample app reproducing it). The reason seems to be the signature of the jar. I opened a ticket to Firebase, asking them why signed jars are causing troubles but they haven't replied yet. So for now I've recompiled your libraries without signing the jar to temporarily solve the issue.

patrickfav commented 6 years ago

The reason seems to be the signature of the jar.

This seems really troubling, that a) they seem to change the content of the jar b) do not support jar signing (but used it for years themselves with APKs). Thanks for raising a ticket in Firebase. I think jar signed jars are a feature of the security libs, so the workaround with removing it seems quite unsatisfying :)

Btw. Bytes & Bcrypt libs are signed

davidmigloz commented 6 years ago

Yes, it's pretty weird. I can understand that the "jetifier" modifies libraries that depend on the support library and are not migrated to AndroidX to make them compatible. But in the case of Bytes, Bcrypt and HKDF, they don't have any dependence on the support library, so what are they modifying and why?

The first time I contacted Firebase support, they didn't even try to reproduce the issue. They wanted me to reproduce it in "isolation":

It seems that you're having some issues when using Performance Monitoring. Aside from our known issues, we don't have a known issue in the SDK that could cause the said error message. Also, we generally don't provide support on issues related to integration with third party libraries so to check if this is indeed an issue with Performance Monitoring SDK, could you please try replicating it using our quickstart app (no third party libraries included)?

And of course, this issue is not reproducible in isolation, so they closed my ticket.

Because the issue is not reproducible consistently, it would be really hard for me to look deeper on this. I'll be needing a solid proof that this is caused by Firebase SDK alone, and not with some integration of third party library. For now, I'll proceed in closing this case. However, if you could replicate the issue locally and consistently, feel free to reach out to us again or just reply back here together with the requested details on my previous email. I'll be more than happy to help.

One week later, I approached them in a different way, and this time it seems they are looking into it:

Thanks for reaching out to us and passing a repro. Let us look into this and get back to you with further details. In the meantime, please feel free to reach out to me in case you have any further information/questions regarding this issue.

So let's see what they reply.

Btw. Bytes & Bcrypt libs are signed

Yes I saw it. I had to recompile all of them to bypass the issue hehe

davidmigloz commented 5 years ago

I did another attempt to update to AndroidX, but without success again...

Firebase Support Team replied that indeed is a bug in their end and they suggested this workaround:

We looked into this and found a bug. However, were able to figure out a workaround for this for you:

Step 1) In your gradle-wrapper.properties file, update the distributionUrl:

distributionUrl=https://services.gradle.org/distributions/gradle-5.0-all.zip

Step 2) In your top level build.gradle file update the Android Gradle Plugin:

classpath 'com.android.tools.build:gradle:3.4.0-alpha05'

Step 3) In your gradle.properties file add below line:

# Blacklist libraries from being Jetified
android.jetifier.blacklist=bcrypt,bytes

Step 4) Clean Build the Project

Running ./gradlew :app:assembleDebug should succeed now.

While we are working on the fix please use the above workaround to get you up and running. My apologies for the wait here once again.

I tried the workaround but it didn't work:

patrickfav commented 5 years ago

Thanks for the update.

patrickfav commented 4 years ago

I'll close this already merged in #51