我正在为Android开发一款支付处理应用程序,我想防止黑客访问APK文件中的任何资源、资产或源代码。

如果有人将.apk扩展名更改为.zip,那么他们可以将其解压缩并轻松访问应用程序的所有资源和资产,并且可以使用dex2jar和Java反编译器访问源代码。对Android APK文件进行反向工程非常容易-有关更多详细信息,请参阅堆栈溢出问题从APK文件到项目的反向工程。

我已经使用了Android SDK提供的Proguard工具。当我对使用签名密钥库和Proguard生成的APK文件进行反向工程时,我得到了混淆的代码。

然而,Android组件的名称保持不变,一些代码(如应用程序中使用的关键值)保持不变。根据Proguard文档,该工具无法混淆Manifest文件中提到的组件。

现在我的问题是:

如何完全防止Android APK的反向工程?这可能吗?我如何保护应用程序的所有资源、资产和源代码,使黑客无法以任何方式破解APK文件?有没有办法让黑客攻击变得更加困难甚至不可能?我还能做什么来保护APK文件中的源代码?


当前回答

此处同意@Muhammad Saqib:https://stackoverflow.com/a/46183706/2496464

@Mumair提供了良好的开始步骤:https://stackoverflow.com/a/35411378/474330

假设您分发到用户设备的所有内容都属于用户,这总是安全的。简单明了。你也许可以使用最新的工具和程序来加密你的知识产权,但没有办法阻止一个有决心的人“研究”你的系统。即使目前的技术可能会让他们很难获得不需要的访问权限,明天,甚至下一个小时,可能会有一些简单的方法!

因此,方程式如下:

说到钱,我们总是认为客户是不可信的。

即使在游戏内经济这么简单的情况下。(尤其是在游戏中!那里有更多“老练”的用户,漏洞在几秒钟内就扩散了!)

我们如何保持安全?

大多数(如果不是全部)关键处理系统(当然还有数据库)都位于服务器端。客户端和服务器之间存在加密通信、验证等。这就是瘦客户端的概念。

其他回答

1.如何完全避免Android APK的反向工程?这可能吗?

这是不可能的

2.如何保护应用程序的所有资源、资产和源代码,使黑客无法以任何方式破解APK文件?

当某人将.apk扩展名更改为.zip,然后在解压缩之后,某人可以轻松地获取所有资源(Manifest.xml除外),但使用APKtool,也可以获取清单文件的真实内容。同样,一个不。

3.有没有办法让黑客攻击变得更加困难甚至不可能?我还能做什么来保护APK文件中的源代码?

同样,不,但你可以在一定程度上防止,

从Web下载资源并执行一些加密过程使用预编译的本机库(C、C++、JNI、NDK)始终执行一些哈希(MD5/SHA密钥或任何其他逻辑)

即使使用Smali,人们也可以使用您的代码。总而言之,这是不可能的。

在计算历史上,当您将软件的工作副本提供给攻击者时,从未有过阻止软件逆向工程的可能。而且,在大多数情况下,这是不可能的。

明白了这一点,就有了一个显而易见的解决方案:不要把你的秘密泄露给攻击者。虽然你不能保护APK的内容,但你可以保护的是你没有分发的任何内容。通常,这是服务器端软件,用于激活、支付、规则执行和其他有趣的代码。您可以通过不在APK中分发有价值的资产来保护它们。相反,设置一个服务器来响应应用程序的请求,“使用”资产(无论这意味着什么),然后将结果发送回应用程序。如果这个模型不适用于你心目中的资产,那么你可能需要重新思考你的战略。

此外,如果你的首要目标是防止应用程序盗版,那就别费心了。你已经在这个问题上花费了比任何反盗版措施都能挽救你的时间和金钱。解决这一问题的投资回报率很低,甚至连思考都没有意义。

应用程序安全的第一条规则:攻击者获得不受限制的物理或电子访问权限的任何机器现在都属于您的攻击者,无论其实际位置或您为此支付的费用。应用程序安全的第二条规则:任何离开攻击者无法穿透的物理边界的软件现在都属于您的攻击者,无论您花费了多少时间对其进行编码。第三条规则:任何离开攻击者无法穿透的物理边界的信息都属于您的攻击者,无论它对您有多大价值。

信息技术安全的基础是基于这三个基本原则;唯一真正安全的计算机是被锁在法拉代笼子里的保险箱里,被锁在钢笼子里。有些计算机的大部分使用寿命都处于这种状态;每年一次(或更少),他们为可信的根认证机构生成私钥(在一大群目击者面前,摄像机记录下他们所在房间的每一寸)。

现在,大多数计算机不在这些类型的环境下使用;他们在户外,通过无线电台连接到互联网。简而言之,他们很脆弱,他们的软件也是如此。因此,他们不值得信任。为了有用,计算机及其软件必须知道或做某些事情,但必须小心确保它们永远不会知道或做足够的事情来造成损坏(至少不会造成超出单个机器范围的永久性损坏)。

你已经知道这一切了;这就是为什么要保护应用程序的代码。但是,其中存在第一个问题;混淆工具可以使代码变得一团糟,让人类试图挖掘,但程序仍然必须运行;这意味着应用程序的实际逻辑流及其使用的数据不受混淆的影响。只要有一点韧性,攻击者就可以简单地对代码进行反混淆,在某些情况下,这甚至是不必要的,在这种情况下,他所看到的不是其他东西,而是他正在寻找的东西。

相反,你应该努力确保攻击者不能对你的代码做任何事情,无论他多么容易获得代码的清晰副本。这意味着,没有硬编码的秘密,因为一旦代码离开你开发它的建筑,这些秘密就不是秘密。

这些硬编码的键值应该从应用程序的源代码中完全删除。相反,他们应该在三个地方之一;设备上的易失性内存,攻击者很难(但仍然不是不可能)获得的脱机副本;永久位于服务器集群上,您可以使用铁腕控制访问;或者存储在与您的设备或服务器无关的第二个数据存储中,例如物理卡或用户的存储器中(这意味着它最终将存储在易失性存储器中,但不需要很长时间)。

考虑以下方案。用户将应用程序的凭据从内存输入设备。不幸的是,您必须相信用户的设备尚未被键盘记录器或木马程序破坏;在这方面,你能做的最好的就是实现多因素安全,记住关于用户使用过的设备的难以伪造的识别信息(MAC/IP、IMEI等),并提供至少一个额外的通道,通过该通道可以验证在陌生设备上的登录尝试。

凭证一旦输入,就会被客户端软件混淆(使用安全散列),并丢弃纯文本凭证;他们达到了目的。混淆后的凭据通过安全通道发送到证书认证服务器,该服务器再次对它们进行散列,以生成用于验证登录有效性的数据。这样,客户端就永远不知道与数据库值实际比较的内容,应用程序服务器永远不知道它接收到的验证内容背后的明文凭证,数据服务器永远不了解它存储的验证数据是如何生成的,中间的人即使安全通道被破坏,也只会看到胡言乱语。

一旦验证,服务器将通过信道发回令牌。令牌仅在安全会话中有用,由随机噪声或会话标识符的加密(因此可验证)副本组成,客户端应用程序必须在同一信道上向服务器发送此令牌,作为任何请求的一部分。客户机应用程序会多次这样做,因为它不能做任何涉及金钱、敏感数据或其他可能会对其造成损害的事情;它必须改为要求服务器执行此任务。客户端应用程序永远不会将任何敏感信息写入设备本身的永久内存,至少不会以明文形式写入;客户端可以通过安全通道向服务器请求对称密钥来加密服务器将记住的任何本地数据;在稍后的会话中,客户端可以向服务器请求相同的密钥来解密数据以在易失性存储器中使用。这些数据也不会是唯一的副本;客户机存储的任何内容也应以某种形式传输到服务器。

显然,这使您的应用程序严重依赖Internet访问;客户端设备不能在没有与服务器的正确连接和服务器的认证的情况下执行其任何基本功能。真的和Facebook没什么不同。

现在,攻击者想要的计算机是你的服务器,因为它而不是客户端应用程序/设备是可以让他赚钱或让其他人痛苦的东西。没关系;与试图保护所有客户机相比,您花费金钱和精力来保护服务器会获得更大的回报。该服务器可以位于各种防火墙和其他电子安全装置的后面,此外,还可以在钢铁、混凝土、钥匙卡/插针访问和24小时视频监控的后面进行物理保护。您的攻击者需要非常老练才能直接访问服务器,而且您应该立即了解这一点。

攻击者所能做的最好的事情就是窃取用户的电话和凭据,并使用客户端的有限权限登录到服务器。如果发生这种情况,就像丢失一张信用卡一样,合法用户应该被指示从他们可以访问的任何电话拨打一个800号码(最好是容易记住的号码,而不是在钱包、钱包或公文包中携带的卡背面,这可能会在移动设备旁边被盗),该电话可以直接连接到您的客户服务。他们声明自己的手机被盗,提供一些基本的唯一标识符,账户被锁定,攻击者可能处理的任何交易都被回滚,攻击者又回到了原点。

基本上这是不可能的。这永远不可能。然而,这是有希望的。你可以使用混淆器来实现,这样一些常见的攻击就更难执行了,包括:

重命名方法/类(因此在反编译器中,您可以获得像.a这样的类型)使控制流混乱(因此在反编译器中,代码很难阅读)加密字符串和可能的资源

我肯定还有其他的,但这是主要的。我在一家名为PreEmptive Solutions的公司工作,负责.NET混淆器。他们还有一个适用于Android的Java混淆器,一个叫做DashO的混淆器。

不过,困惑总是有代价的。值得注意的是,性能通常更差,通常需要一些额外的时间来发布。然而,如果你的知识产权对你来说非常重要,那么它通常是值得的。

否则,你唯一的选择就是让你的Android应用程序直接传递到一个承载你应用程序所有真实逻辑的服务器。这有其自身的问题,因为这意味着用户必须连接到Internet才能使用您的应用程序。

此外,不仅仅是Android有这个问题。这是每个应用商店的问题。这只是获取程序包文件有多困难的问题(例如,我不相信在iPhone上很容易,但仍然有可能)。

100%避免Android APK的反向工程是不可能的,但您可以使用以下方法避免提取更多数据,如源代码、APK中的资产和资源:

使用ProGuard混淆应用程序代码使用使用C和C++的NDK将应用程序核心和安全部分代码放在.so文件中为了保护资源,不要将所有重要资源都包含在APK的资产文件夹中。在应用程序首次启动时下载这些资源。