本文概述
- 1.安装加密插件
- 2.自定义应加密的文件
- 3.验证文件是否已加密
- 额外的安全性
文章图片
【如何加密(保护)Android Cordova应用程序的源代码】而且, 如果你尝试编辑一些提取的文件(我们的app.js), 那么它将包含:
文章图片
你看见我看到的了吗 ?你的应用程序的源代码, 任何知道如何使用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文件夹的内容:
文章图片
如你所见, 文件的结构保持不变。最后, 使用代码编辑器编辑任何文件(只要不将其排除在加密之外), 你将看到文件的内容已加密:
文章图片
现在看来不可读, 不是吗?安装的插件将在运行时解密文件, 你的应用程序将按预期运行, 并且你的源代码具有更高的保护级别。
额外的安全性 你可以使用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开发人员, 则可能不了解此问题, 请分享此文章。编码愉快!
推荐阅读
- 如何在Cordova应用程序中在Android上启用实质性本机主题
- 如何在Android的Cordova应用程序中启用移动到SD卡功能
- 如何使用Cordova生成和扫描二维码
- 如何清理我的Android模拟器中不需要的应用程序()
- 没有USB设备android studio 3.1.3
- Android模拟器没有显示画布绘图
- 无法加载android sdk实例。请检查您的互联网连接
- Wi-fi无法连接到Android Studio模拟器
- 模拟器不接受ANDROID_SDK_ROOT