如何加密(保护)Android Cordova应用程序的源代码

本文概述

  • 1.安装加密插件
  • 2.自定义应加密的文件
  • 3.验证文件是否已加密
  • 额外的安全性
如你所知, apk文件实际上只是一个zip存档, 因此你可以尝试将文件重命名(或简单地迫使你的解压缩工具打开apk文件)为appname.apk.zip并使用任何zip实用程序将其解压缩。在此示例中, 我们将构建一个使用React(不是本地本机)和webpack的应用程序, 以在单个文件app.js中生成所有js代码。然后, 我们使用cordova build android – release构建应用程序, 并使用zip实用程序在project / platforms / android / build / outputs / apk中查看apk生成文件(构建或调试)的内容(在这种情况下, 我们将使用WinRAR):
如何加密(保护)Android Cordova应用程序的源代码

文章图片
【如何加密(保护)Android Cordova应用程序的源代码】而且, 如果你尝试编辑一些提取的文件(我们的app.js), 那么它将包含:
如何加密(保护)Android Cordova应用程序的源代码

文章图片
你看见我看到的了吗 ?你的应用程序的源代码, 任何知道如何使用zip实用程序打开APK的人都可以阅读。尽管我们的代码被最小化用于生产(不是由cordova而是由我们制造), 但该代码仍然可见, 但可以清晰地打印出来, 因此可读性强。 (显然)这不太好, 因为你的代码可能会暴露功能的安全漏洞(如果有的话), 例如登录应用程序, 付款流程等。
正如许多开发人员所说, 你可能需要知道, 针对逆向工程没有100%的安全性。尽管你可以做更多的事情来保护应用程序的代码, 但实际上, 这对于大多数普通用户来说要困难得多, 他们只是在Google上搜索” 如何破解APK” 。如果有人真的想对你的应用程序进行黑客入侵, 则可以迟早对其进行黑客入侵(除非你的应用程序与服务器通信很多, 并且大多数功能不在设备上)。
在本文中, 你将学习如何在Cordova中保护(或至少提高保护级别)应用程序的源代码。
1.安装加密插件 我们将使用cordova-plugin-crypt-file插件来加密项目的www文件夹内的所有文件(生成的apk中包含的文件)。它可以在任何cordova项目中使用(即使它使用Crosswalk), 尽管本教程仅适用于Android, 但该插件本身也支持iOS平台。
在终端中使用以下命令安装插件(一旦你位于项目文件夹中):
cordova plugin add cordova-plugin-crypt-file

插件安装完成后, 它将自动开始工作, 并且在每个版本上, 它将对文件进行加密。
加密如何工作?
该插件使用AES / CBC / PKCS5Padding加密算法来加密文件。插件会在应用程序编译期间使用随机生成的加密密钥和初始化向量(IV)对文件进行加密(这意味着将不会修改项目内部的原始文件, 仅会修改生成的APK的文件) 。与预期的一样, 每次你的应用程序在已安装设备上启动时, 文件都会被解密。
2.自定义应加密的文件 如前所述, 文件已加密, 无法使用Javascript对其解密。如果不需要加密文件, 则可以使用自定义正则表达式自定义要加密的文件。但是, 你将需要在插件文件中指定此名称。首先打开/ project / plugins / cordova-plugin-crypt-file中的plugin.xml并修改cryptfiles标记。
默认情况下, 插件包含以下正则表达式, 用于加密www目录中的所有css, htm, html和js文件:
< cryptfiles> < include> < file regex="\.(htm|html|js|css)$" /> < /include> < exclude> < /exclude> < /cryptfiles>

只需自定义正则表达式以指定将要加密的文件, 例如, 以下标记将仅压缩html, htm, js, 而不压缩css文件, 并使用名称示例排除单个JS文件:
< cryptfiles> < include> < file regex="\.(htm|html|js)$" /> < /include> < exclude> < file regex="example.js" /> < /exclude> < /cryptfiles>

完成更改后, 保存更改。
3.验证文件是否已加密 现在, 在安装插件(以及可选的自定义加密文件)之后, 你可以验证插件是否正常工作。重复本文开头提到的相同过程。构建你的应用程序(调试或发布模式), 并使用zip实用程序查看apk(资产/ www)中www文件夹的内容:
如何加密(保护)Android Cordova应用程序的源代码

文章图片
如你所见, 文件的结构保持不变。最后, 使用代码编辑器编辑任何文件(只要不将其排除在加密之外), 你将看到文件的内容已加密:
如何加密(保护)Android Cordova应用程序的源代码

文章图片
现在看来不可读, 不是吗?安装的插件将在运行时解密文件, 你的应用程序将按预期运行, 并且你的源代码具有更高的保护级别。
额外的安全性 你可以使用Cordova在生成的APK中使用ProGuard。 ProGuard优化字节码, 删除未使用的代码指令, 并用短名称混淆其余的类, 字段和方法。混淆的代码使你的APK难以进行反向工程, 当你的应用使用对安全敏感的功能(例如许可验证)时, 这尤其有价值。
在/ project / platforms / android文件夹中创建具有以下内容的proguard-rules.pro文件:
# By default, the flags in this file are appended to flags specified# in /usr/share/android-studio/data/sdk/tools/proguard/proguard-android.txt# For more details, see#http://developer.android.com/guide/developing/tools/proguard.html##---------------Begin: proguard configuration common for all Android apps -----------optimizationpasses 5-dontusemixedcaseclassnames-dontskipnonpubliclibraryclasses-dontskipnonpubliclibraryclassmembers-dontpreverify-verbose-dump class_files.txt-printseeds seeds.txt-printusage unused.txt-printmapping mapping.txt-optimizations !code/simplification/arithmetic, !field/*, !class/merging/*-allowaccessmodification-keepattributes *Annotation*-renamesourcefileattribute SourceFile-keepattributes SourceFile, LineNumberTable-repackageclasses ''-keep public class * extends android.app.Activity-keep public class * extends android.app.Application-keep public class * extends android.app.Service-keep public class * extends android.content.BroadcastReceiver-keep public class * extends android.content.ContentProvider-keep public class * extends android.app.backup.BackupAgentHelper-keep public class * extends android.preference.Preference-keep public class com.android.vending.licensing.ILicensingService-dontnote com.android.vending.licensing.ILicensingService# Explicitly preserve all serialization members. The Serializable interface# is only a marker interface, so it wouldn't save them.-keepclassmembers class * implements java.io.Serializable {static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); }# Preserve all native method names and the names of their classes.-keepclasseswithmembernames class * {native < methods> ; }-keepclasseswithmembernames class * {public < init> (android.content.Context, android.util.AttributeSet); }-keepclasseswithmembernames class * {public < init> (android.content.Context, android.util.AttributeSet, int); }# Preserve static fields of inner classes of R classes that might be accessed# through introspection.-keepclassmembers class **.R$* {public static < fields> ; }# Preserve the special static methods that are required in all enumeration classes.-keepclassmembers enum * {public static **[] values(); public static ** valueOf(java.lang.String); }-keep public class * {public protected *; }-keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *; }##---------------End: proguard configuration common for all Android apps ----------#---------------Begin: proguard configuration for support library-----------keep class android.support.v4.app.** { *; }-keep interface android.support.v4.app.** { *; }-keep class com.actionbarsherlock.** { *; }-keep interface com.actionbarsherlock.** { *; }# The support library contains references to newer platform versions.# Don't warn about those in case this app is linking against an older# platform version. We know about them, and they are safe.-dontwarn android.support.**-dontwarn com.google.ads.**##---------------End: proguard configuration for Gson----------##---------------Begin: proguard configuration for Gson----------# Gson uses generic type information stored in a class file when working with fields. Proguard# removes such information by default, so configure it to keep all of it.-keepattributes Signature# For using GSON @Expose annotation-keepattributes *Annotation*# Gson specific classes-keep class sun.misc.Unsafe { *; }#-keep class com.google.gson.stream.** { *; }# Application classes that will be serialized/deserialized over Gson-keep class com.example.model.** { *; }##---------------End: proguard configuration for Gson----------# If your project uses WebView with JS, uncomment the following# and specify the fully qualified class name to the JavaScript interface# class:#-keepclassmembers class fqcn.of.javascript.interface.for.webview {#public *; #}

然后编辑build.gradle文件(在/ project / platforms / android内或创建一个Cordova插件, 将其自动添加到构建文件中):
android {...buildTypes {debug {minifyEnabled trueuseProguard trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}release {minifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}...}

最后一步, 使用cordova build android – release在发布模式下构建apk, 就可以开始了。
ProGuard会缩小你的代码, 使其难以阅读(最小化), 这可能会减慢逆向工程过程。尽管ProGuard不会混淆字符串常量, 但它更专门用于Android, DexGuard的闭源同级, 并提供了附加的应用程序保护技术, 例如字符串加密和类加密。
如果你认识Cordova开发人员, 则可能不了解此问题, 请分享此文章。编码愉快!

    推荐阅读