如何避免一个APK文件被反向工程化
如何避免一个APK文件被反向工程化
我正在为Android开发一个支付处理应用程序,我希望阻止黑客从APK文件中访问任何资源、资产或源代码。
如果有人将.apk扩展名更改为.zip,那么他们可以解压缩它并轻松访问所有应用程序的资源和资产,并使用dex2jar和Java反编译器,他们还可以访问源代码。反向工程一个Android APK文件非常容易-有关更多详情,请参见Stack Overflow问题从APK文件反向工程到项目。
我使用了Android SDK提供的Proguard工具。当我反向工程使用签名密钥库和Proguard生成的APK文件时,我得到了混淆的代码。
但是,Android组件的名称保持不变,一些代码(例如应用程序中使用的键值)保持不变。根据Proguard文档,该工具无法混淆在Manifest文件中提到的组件。
现在我的问题是:
- 我如何完全防止反向工程Android APK?这个可能吗?
- 我如何保护所有应用程序的资源、资产和源代码,以便黑客无法以任何方式破解APK文件?
- 是否有一种方法使破解更加困难甚至不可能?我可以采取什么措施来保护我的APK文件中的源代码?
据我所知,你不能保护/res目录中的文件,在目前的状态下就已经受到了保护。
但是,您可以采取措施来保护您的源代码,或者至少保护它的功能,而不会影响所有的功能。
- 使用诸如ProGuard之类的工具。这些工具会混淆您的代码,使其在反编译时难以阅读,如果不是不可能的话。
- 将服务的最关键部分移出应用程序,并移到Web服务中,使用PHP等服务器端语言来隐藏它们。例如,如果你有一个算法,你为它编写了一百万美元。显然,你不希望人们从你的应用程序中窃取它。将算法移动,并在远程服务器上处理数据,并使用应用程序简单地为其提供数据。或者使用NDK将它们原生地写入.so文件中,这些文件比apk文件更不容易被反编译。我认为,现在甚至没有针对.so文件的反编译器(即使有,它的效果也不会像Java反编译器那么好)。此外,正如@nikolay在评论中提到的那样,与服务器和设备之间的交互时,应该使用SSL。
- 在设备上存储值时,请勿以原始格式存储它们。例如,如果你有一款游戏,并将用户拥有的游戏货币数存储在SharedPreferences中。假设当前是
10000
枚硬币。不要直接保存10000
,而是使用((currency*2)+1)/13
这样的算法进行保存。因此,您保存1538.53846154
而不是10000
到SharedPreferences中。然而,上面的示例并不完美,您必须努力找出一个不会丢失货币数的等式等。 - 你可以对服务器端任务做同样的事情。现在以你的支付处理应用程序为例。假设用户必须支付
$200
。不要向服务器发送一个原始的$200
值,而是发送一系列较小的,预定义的值,这些值相加起来等于$200
。例如,在服务器上拥有一个将单词与值相对应的文件或表。因此,假设Charlie
对应于$47
,而John
对应于$3
。因此,您可以发送Charlie
四次和John
四次而不是发送$200
。在服务器上,解释它们的含义并将它们加起来。这样可以防止黑客向您的服务器发送任意值,因为他们不知道什么单词对应什么值。作为安全措施的附加条件,您可以像第3点那样采用类似的等式,并在n
天内更改关键词。 - 最后,你可以将随机无用的源代码插入你的应用程序中,以便黑客正在寻找一根针在一个大堆草中。插入从互联网上的随机类中获取的片段或仅用于计算随机事物(如斐波那契数列)的函数。确保这些类编译成功,但不使用这些类来实现应用程序的实际功能。添加足够多的这些虚假类,黑客会很难找到您的真正代码。
总之,没有办法以100%的方式保护您的应用程序。你可以让它变得更难,但不是不可能的。您的Web服务器可能会被入侵,黑客可能会通过监控多个交易金额和您发送的关键字来确定您的关键字,黑客可能会费力地浏览源代码并找出哪些代码是虚假的。
你只能反抗,但永远无法取胜。
1. 我该如何完全避免Android APK的逆向工程?这可能吗?\n据我所知,没有任何技巧可以完全避免逆向工程。\n并且@inazaruk很好地说过:无论你对代码做什么,潜在的攻击者都能以任何可行的方式对其进行更改。你基本上无法保护你的应用程序免受修改的影响。而你加入的任何保护措施都可以被禁用/删除。\n\n2. 我该如何保护所有应用程序的资源、资产和源代码,使黑客无法以任何方式入侵APK文件?\n你可以使用不同的技巧使黑客更难入侵。例如,如果是Java代码,可以使用模糊化。这通常会显著减缓逆向工程的速度。\n\n3. 是否有办法让黑客更加困难甚至不可能入侵?我该采取什么措施来保护APK文件中的源代码?\n正如大家所说,你可能已经知道,没有100%的安全。但对于Android而言,谷歌已经内置了ProGuard。如果你有包括共享库的选项,可以在C++中包括所需的代码以验证文件大小、集成等。如果你需要在每次构建时向APK的库文件夹中添加外部本地库,那么你可以按照下面的建议使用它。\n将库放在本地库路径中,该路径默认为项目文件夹中的“libs”。如果你为“armeabi”目标构建本地代码,那么放置在“libs/armeabi”下,如果是“armeabi-v7a”构建的,则放置在“libs/armeabi-v7a”下。\n
/libs/armeabi/libstuff.so