atsign-foundation / at_java

Java libraries, tools, samples and examples for the atPlatform
BSD 3-Clause "New" or "Revised" License
2 stars 19 forks source link

Android Studio emulator does not support AES SIC #73

Open JeremyTubongbanua opened 1 year ago

JeremyTubongbanua commented 1 year ago

Describe the bug Making an Android App and using at_java as a dependency and trying to use AES SIC does not seem to work. Sample size is 1 for this bug.

To Reproduce Use any at_java functionality that involves AES decryption/encryption

Expected behavior Work

Screenshots image

Smartphone (please complete the following information): To be filled

Additional context To fix, use AES/CTR instead.

From this wikipedia page, SIC work the exact same as CTR. "Note: CTR mode (CM) is also known as integer counter mode (ICM) and segmented integer counter (SIC) mode." So to fix this bug, simply change SIC to CTR. Maybe it's as simple as Android Studio's Java encryption library is missing the aliases?

Maybe have a separate release for developers who are making an android app through android studio?

gkc commented 1 year ago

SIC and CTR are the same. Java's CTR is borked as it does not support padding, but our dart libs use SIC with padding. Hence using BouncyCastle provider so can use SIC with padding so can interop with Dart

Running java client on Linux / Mac / Windows works fine; so problem is likely android specific, possibly some issue with loading the bouncy castle provider?

gkc commented 1 year ago

Maybe try what's suggested here: https://stackoverflow.com/questions/2584401/how-to-add-bouncy-castle-algorithm-to-android

Quote:

On the other hand if you want to write code that takes advantage of Bouncy Castle via the security provider then you should first replace the built-in Android Bouncy Castle security provider with the standard one since Java does not allow two security providers with the same name. This should be done as early as possible during application startup:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class MyApplication extends Application {
    static {
        Security.removeProvider("BC");
        // Confirm that positioning this provider at the end works for your needs!
        Security.addProvider(new BouncyCastleProvider());
    }
}

Note that Java security providers rely heavily on reflection. If you are using obfuscation or shrinking your project then the Bouncy Castle classes will end being culled or renamed inappropriately, to prevent that you need to add the following or similar to proguard.pro file:

-keep class org.bouncycastle.jcajce.provider.** { *; }
-keep class org.bouncycastle.jce.provider.** { *; }
gkc commented 1 year ago

Here's some gory background detail: https://bugs.openjdk.org/browse/JDK-6634037

Basically, the JDK implementers seem to have ignored part of the specification which says "padding MAY be included" and didn't support it. The Dart implementation we decided to use (the encrypt package) by default uses SIC mode with PKCS7Padding for AES: AES(this.key, {this.mode = AESMode.sic, this.padding = 'PKCS7'}) and we are using the default.

Hence that's what I needed to use in the Java SDK, but Java didn't support it natively, so I had to use the BouncyCastle provider

Bottom line: For interoperability across all our client SDKs right now, they must all use the SIC mode (aka CTR aka ICM) and they must use it with PKCS7Padding