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

本文概述

如你所知, 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):

加密源代码Cordova应用

而且, 如果你尝试编辑一些提取的文件(我们的app.js), 那么它将包含:

Cordova APK源代码文件内容

你看见我看到的了吗 ?你的应用程序的源代码, 任何知道如何使用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文件夹的内容:

请参阅Apk Content Zip实用程序

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

加密的文件内容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 true
            useProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    ...
}

最后一步, 使用cordova build android –release在发布模式下构建apk, 就可以开始了。

ProGuard会缩小你的代码, 使其难以阅读(最小化), 这可能会减慢逆向工程过程。尽管ProGuard不会混淆字符串常量, 但它更专门用于Android, DexGuard的闭源同级, 并提供了附加的应用程序保护技术, 例如字符串加密和类加密。

如果你认识Cordova开发人员, 则可能不了解此问题, 请分享此文章。编码愉快!

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?