Skip to content

Instantly share code, notes, and snippets.

@developernotes
Created July 3, 2012 15:47
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save developernotes/3040592 to your computer and use it in GitHub Desktop.
Save developernotes/3040592 to your computer and use it in GitHub Desktop.
ProGuard with SQLCipher for Android
-libraryjars libs/commons-codec.jar
-libraryjars libs/guava-r09.jar
-libraryjars libs/sqlcipher.jar
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-dontobfuscate
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-dontwarn javax.annotation.**
-dontwarn android.app.**
-dontwarn android.support.**
-dontwarn android.view.**
-dontwarn android.widget.**
-dontwarn com.google.common.primitives.**
-dontwarn **CompatHoneycomb
-dontwarn **CompatHoneycombMR2
-dontwarn **CompatCreatorHoneycombMR2
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-keep public class net.sqlcipher.** {
*;
}
-keep public class net.sqlcipher.database.** {
*;
}
@DongChengliang
Copy link

10 -dontobfuscate?

Is this a must? Then we can't obfuscate the whole project because of sqlcipher? Then proguard lose most of its meaning!

@developernotes
Copy link
Author

Hi @DongChengliang

No, that is not required, however ProGuard does provide other useful features such as file shrinking and optimization. I will remove the -dontobfuscate option when I include this with SQLCipher for Android to remove any confusion.

@cthulhuplush
Copy link

I just spend a few hours making this work.
This:
-keep public class net.sqlcipher.** { ; }
-keep public class net.sqlcipher.database.
* { *; }

needs to be:
-keep class net.sqlcipher.** { ; }
-keep class net.sqlcipher.database.
* { *; }

Remove that 'public' keyword!!!!!

@adrianchifor
Copy link

-keep class net.sqlcipher.** { ; }

The above already includes:
-keep class net.sqlcipher.database.** { *; }

@uhaldejm
Copy link

I just spend a few hours making this work.
This:
-keep public class net.sqlcipher.** { ; } -keep public class net.sqlcipher.database.* { *; }

needs to be:
-keep class net.sqlcipher.** { ; } -keep class net.sqlcipher.database.* { *; }

Remove that 'public' keyword!!!!!

Thanks for saving me a headache :)

-keep class net.sqlcipher.** {*;}

@Krammig
Copy link

Krammig commented Oct 4, 2023

@developernotes

I just spend a few hours making this work.
This:
-keep public class net.sqlcipher.** { ; } -keep public class net.sqlcipher.database.* { *; }

needs to be:
-keep class net.sqlcipher.** { ; } -keep class net.sqlcipher.database.* { *; }

Remove that 'public' keyword!!!!!

Thanks for saving me a headache :)

So why haven't you updated the original code ??

@developernotes
Copy link
Author

@Krammig the android-database-sqlcipher library has been deprecated. The newer sqlcipher-android library is the long-term supported replacement. We will plan to add ProGuard support in a future release.

@orestesgaolin
Copy link

If you switched to the sqlcipher-android then the new proguard rules (that worked for us) are:

-keep class net.zetetic.database.sqlcipher.* { *; }
-keep class net.zetetic.sqlcipher.** { *; }

@carloxavier
Copy link

carloxavier commented Oct 16, 2023

@orestesgaolin it seems there's a typo on the second package you used for the rule, it seems to me the rules for the newer library should be:


-keep class net.zetetic.database.sqlcipher.* { *; }
-keep class net.zetetic.database.** { *; }

@melsaq
Copy link

melsaq commented Oct 17, 2023

@carloxavier and @orestesgaolin am getting below error after trying both proguard rules you have mentioned: java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ) at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(Native Method) at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:5) at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:2) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:7) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:4) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:2) at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:6) at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1) at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:7) at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:122) at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:3)

@ovUdemy
Copy link

ovUdemy commented Oct 17, 2023

I get a runtime error
No pending exception expected: java.lang.NoSuchFieldError: no "J" field "mNativeHandle" in class "Lnet/sqlcipher/database/SQLiteDatabase;" or its superclasses

@carloxavier
Copy link

carloxavier commented Oct 18, 2023

@melsaq @ovUdemy my comment had a markdown typo, please try with these rules:

-keep class net.zetetic.database.sqlcipher.* { *; }
-keep class net.zetetic.database.** { *; }

@melsaq
Copy link

melsaq commented Oct 18, 2023

@carloxavier I have used that but still getting below error: java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ) at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(Native Method) at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:5) at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:2) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:7) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:4) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:2) at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:6) at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1) at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:7) at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:120) at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:3)

My dbhelper constructor: `public DBHelper(@nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);

    Thread backgroundThread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.loadLibrary("sqlcipher");

            SECRET_KEY = PassphraseGenerator.retrievePassphraseFromKeystore();
            // Specify the database file
            assert context != null;
            File databaseFile = context.getDatabasePath(DATABASE_NAME);
            // Create the database
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(databaseFile, SECRET_KEY, null, null, null);

            db.close();
        }
    });

    backgroundThread.start();
}`

my proguard rules: `-dontwarn **
-optimizations !code/allocation/variable
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontobfuscate
-verbose
-optimizations !code/simplification/arithmetic,!field/,!class/merging/,!code/allocation/variable

-keep class net.zetetic.database.sqlcipher.* { ; }
-keep class net.zetetic.database.
* { *; }

-dontwarn net.zetetic.**

-keep class com.vortex.mlera.DBHelper.** { *; }

-keep class net.openid.appauth.** {*;}

-keep class org.sqlite.** { *; }

-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.view.ViewCompat$Api* {
;
}
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.view.WindowInsetsCompat$Impl {
;
}
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.app.NotificationCompat$$ApiImpl {
;
}
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.os.UserHandleCompat$ApiImpl {
;
}
-keepclassmembernames,allowobfuscation,allowshrinking class androidx.core.widget.EdgeEffectCompat$Api
Impl {
;
}

-dontwarn org.sqlite.**

-keepclasseswithmembernames class * {
native ;
}

-keep public class com.vortex.mlera.auth.AuthStateManager.* {*;}

-keep class org.json.** {*;}

-keepattributes Signature

For using GSON @expose annotation

-keepattributes Annotation

Gson specific classes

-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

Application classes that will be serialized/deserialized over Gson

-keep class com.google.gson.examples.android.model.** { ; }

Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,

JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)

-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

Prevent R8 from leaving Data object members always null

-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName ;
}

-keep class com.android.volley.** { ; }
-keep class org.apache.commons.logging.
*

-keepattributes Annotation

-dontwarn org.apache.**

-keep class net.openid.appauth.** {*;}

-keep class com.basgeekball.awesomevalidation.** {*;}

-keep class com.github.denzcoskun.** {*;}

-keep class me.dm7.barcodescanner.** {*;}

-keep class com.github.gcacace.** {*;}

-keep class com.karumi.** {*;}

-keep class com.auth0.android.** {*;}

-keep class org.json.** {*;}

-keep public class com.vortex.mlera.auth.AuthStateManager.* {*;}

-keep class com.shockwave.**

-assumenosideeffects class com.sec.android.app.camera.** {*;}

-assumenosideeffects class android.hardware.** {*;}

-assumenosideeffects class android.view.WindowManager.** {*;}

-assumenosideeffects class android.util.AndroidRuntimeException.** {*;}

-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application

-dontwarn javax.annotation.**

-dontwarn android.app.**
-dontwarn android.support.**
-dontwarn android.view.**
-dontwarn android.widget.**

-dontwarn com.google.common.primitives.**

-dontwarn **CompatHoneycomb
-dontwarn **CompatHoneycombMR2
-dontwarn **CompatCreatorHoneycombMR2

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class *.R$ {
public static ;
}`
It is only working when minify and shrinkresources are false

@ovUdemy
Copy link

ovUdemy commented Oct 23, 2023

@carloxavier
this

-keep class net.zetetic.database.sqlcipher.* { ; }
-keep class net.zetetic.database.
* { *; }

still gives me No pending exception expected: java.lang.NoSuchFieldError: no "J" field "mNativeHandle" in class "Lnet/sqlcipher/database/SQLiteDatabase;" or its superclasses

@carloxavier
Copy link

@ovUdemy the posted rules are for the newer sqlcipher library, check here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment