如何避免APK文件的反向工程?


764

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

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

我已经使用了Android SDK随附的Proguard工具。当我反向工程使用签名的密钥库和Proguard生成的APK文件时,我得到的代码很混乱。

但是,Android组件的名称保持不变,某些代码(如应用中使用的键值)保持不变。根据Proguard文档,该工具不能混淆清单文件中提到的组件。

现在我的问题是:

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

120
听起来如果您的付款处理方案依赖于客户的机密操作,您可能正在使用“默默无闻的安全性”。
PeterJ 2012年

43
您是否考虑过用C / C ++编写代码的重要部分并将其添加为已编译的库?可以将它们分解为汇编代码,但是从汇编中对大型库进行反向工程非常耗时。
Leo


60
欢迎来到创建任何数字资产的基本问题。黑客可以降低到机器指令的级别,因此,如果计算机可以读取文件,则可以将其黑客打开/复制,毫无疑问的混淆或DRM可以完全阻止坚定的黑客。如果需要安全性,请确保私钥永远不会在源中,并且在设计阶段知道只有隔离(远程和/或专用硬件)才能保护它们。
基思(Keith)

16
请注意,根据您的付款处理应用程序的工作情况,可能会有影响您应用程序的法规和法律政策,并可能使您面临严厉的处罚:请参阅pcicomplianceguide.org/pcifaqs.php#11开始的PCI合规性。
bloopletech 2012年

Answers:


371

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

AFAIK,没有任何技巧可以完全避免逆向工程。

@inazaruk也很好地说:无论您对代码做什么,潜在的攻击者都可以通过其认为可行的任何方式对其进行更改。您基本上不能保护您的应用程序不被修改。并且您放置在其中的所有保护措施都可以被禁用/删除。

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

您可以采取不同的技巧来使黑客攻击更加困难。例如,使用混淆(如果是Java代码)。这通常会大大降低反向工程的速度。

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

众所周知,您可能知道,没有100%的安全性。但是Google内置的Android的起点是ProGuard。如果可以选择包含共享库,则可以在C ++中包含所需的代码以验证文件大小,集成等。如果需要在每次构建时向APK的库文件夹中添加外部本机库,则可以使用它通过以下建议。

将库放在本机库路径中,该路径默认为项目文件夹中的“ libs”。如果您为“ armeabi”目标构建了本机代码,则将其放在libs / armeabi下。如果它是使用armeabi-v7a构建的,则将其放在 libs / armeabi-v7a下。

<project>/libs/armeabi/libstuff.so

1
对于支付交易,我使用了ISO 8585标准,现在该标准的架构使用Java的HashMap集合在键值对中,当我对apk进行逆向工程时,我将获得所有架构。是否有可能避免架构获取通过逆向工程暴露。您对共享库的最后建议在这种情况下是否有用?难道您有任何链接,以便我可以接触到android中的共享库。
sachin003

4
如何在代码中加密字符串并在运行时解密它们呢?如果像其他人所建议的那样在远程服务器上进行解密,则不会出现解密密钥在源中的问题。
kutschkem

是的,加密是一种方式,但是不确定是否没有被破解。如果我要加密String以便对其解密,则我在代码中需要一个唯一的ID。如果有人能够反编译,则很容易获得唯一ID。
Bhavesh Patadiya

为什么添加“已编辑”内容?一切正常。
Mohammed Azharuddin Shaikh

@hotveryspicy:是的,我现在已经从answer.i中删除了“已编辑”标记。因为他想了解有关共享库在这种情况下如何有用的信息,所以我已经编辑了答案。
Bhavesh Patadiya

126

AFAIK,您不能再保护/ res目录中的文件,而不能立即保护它们。

但是,您可以采取一些步骤来保护源代码,或者至少要保护源代码而不是全部。

  1. 使用ProGuard之类的工具。这些会混淆您的代码,并且即使不是不可能的话,在反编译时也很难阅读。
  2. 将服务中最关键的部分移出应用程序,并移到Web服务中,隐藏在服务器端语言(如PHP)的后面。例如,如果您有一种算法需要花费一百万美元来编写。您显然不希望别人从您的应用程序中窃取它。移动算法并使其在远程服务器上处理数据,然后使用该应用程序简单地向其提供数据。或使用NDK将其本机写入.so文件中,而与apks相比,它们反编译的可能性要小得多。我认为到目前为止,.so文件的反编译器还不存在(即使确实如此,它也不如Java的反编译器)。此外,正如注释中提到的@nikolay一样,在服务器和设备之间进行交互时应使用SSL。
  3. 在设备上存储值时,请勿以原始格式存储它们。例如,如果您有一个游戏,并且要存储用户在SharedPreferences中拥有的游戏币数量。假设它是10000硬币。与其10000直接保存,不如使用算法将其保存((currency*2)+1)/13。因此10000,您可以保存1538.53846154到SharedPreferences 中,而不是。但是,上面的示例并不是完美的,您必须努力想出一个不会因舍入误差等因素而浪费时间的方程式。
  4. 您可以对服务器端任务执行类似的操作。现在举个例子,让我们实际使用您的付款处理应用程序。假设用户必须付款$200。而不是向$200服务器发送原始值,而是发送一系列较小的预定义值(总计为)$200。例如,在您的服务器上有一个文件或表格,将单词和值等同起来。所以我们可以说是Charlie对应于$47,和John$3。因此$200,您可以发送Charlie四次,而不必发送,John四次。在服务器上,解释它们的含义并将其加起来。这可以防止黑客将任意值发送到您的服务器,因为他们不知道哪个单词对应什么值。为了增加安全性,您也可以使用类似于第3点的公式,并每隔n几天更改关键字。
  5. 最后,您可以将无用的随机源代码插入您的应用程序,以使黑客在大海捞针中寻找针头。插入包含来自互联网的摘要的随机类,或者仅插入用于计算诸如斐波那契数列之类的随机事物的函数。确保可以编译这些类,但应用程序的实际功能未使用这些类。添加足够多的这些错误类,黑客将很难找到您的真实代码。

总而言之,没有办法100%保护您的应用程序。您可以使其更困难,但并非没有可能。您的Web服务器可能受到威胁,黑客可能会通过监视多个交易金额和您为其发送的关键字来找出您的关键字,黑客可能会费心地查看源代码并找出哪个代码是假的。

您只能反击,但永远不会赢。


136
不要使用发送到服务器的值来欺骗,而应使用SSL并正确验证服务器证书。默默无闻的安全性通常不是一个好主意。
Nikolay Elenkov 2012年

48
您可以将无用的随机源代码插入应用程序。这也无济于事。这只会使您的应用程序膨胀,同时也使维护变得更加困难。
Anirudh Ramanathan 2012年

4
您还可以伪造使用无用的代码,然后将数据发送到服务器,服务器将丢弃它。可能是虚假的安全性,但潜在的黑客却为此感到痛苦,对吧?
Benoit Duffez,2012年

19
如果您的算法价值一百万美元,那么仅仅因为没有用于.so文件的反编译器并不意味着我无法阅读汇编:)这些算法中的大多数都陷入了同一个陷阱,只是混淆而不是适当地保护自己。模糊处理仅在不值得攻击者花费时间的情况下才有效,因此,如果您基于这些技术构建某些内容,则最好希望它们不受欢迎,否则您将被搞砸,因为您的代码库突然变得无法维护,并且需要巨大的变化。
Phoshi 2012年

23
我不明白为什么这个答案得分如此之高。3.和4.只是一个简单的傻子,根本就没有安全性。
Matti Virkkunen

117

当您将软件的有效副本提供给攻击者时,在计算历史上的任何时候都不可能阻止软件的逆向工程。而且,极有可能永远不可能

据了解,有一个显而易见的解决方案:不要将您的秘密透露给攻击者。虽然您无法保护APK的内容,但是您可以保护的是您不分发的任何内容。通常,这是服务器端软件,用于激活,付款,规则执行以及其他多汁的代码。您可以通过不在 APK中分发有价值的资产来保护它们。而是设置一个服务器来响应您的应用程序的请求,“使用”资产(可能意味着任何意思),然后将结果发送回应用程序。如果该模型不适用于您所考虑的资产,那么您可能需要重新考虑您的战略。

另外,如果您的主要目标是防止应用盗版那就不要打扰。在此问题上,您已经花费了更多的时间和金钱,而任何反盗版措施都可能希望拯救您。解决该问题的投资回报率很低,以至于甚至没有考虑。


21
第一段是最佳答案。如果您的攻击者控制了硬件,则他们总是能够以某种方式击败您的软件。真正需要保护的任何内容都必须保留在您控制的硬件上,就这么简单。最后一点是关于ROI的内容。
丹尼尔·普赖登

88

应用程序安全性的第一法则:攻击者获得不受限制的物理或电子访问的任何计算机现在都属于您的攻击者,无论它实际在何处或您为之付款。

应用程序安全性的第二条规则:任何离开攻击者无法进入的物理边界的软件现在都属于您的攻击者,无论您花了多少时间对其进行编码。

第三条规则:任何离开攻击者无法穿透的相同物理边界的信息现在都属于您的攻击者,无论它对您有多有价值。

信息技术安全的基础是基于这三个基本原则。唯一真正安全的计算机是锁在法拉第笼,钢笼中的保险箱中的计算机。有些计算机将大部分服务用于这种状态。每年一次(或更短时间),它们会为受信任的根证书颁发机构生成私钥(在许多见证人的面前,摄像机会记录他们所在房间的每一英寸)。

现在,大多数计算机不在这种类型的环境下使用。它们实际上是开放的,通过无线信道连接到Internet。简而言之,他们和软件一样容易受到攻击。因此,它们不被信任。为了使其有用,计算机及其软件在某些方面必须知道或要做某些事情,但必须小心以确保它们永远不会知道或做不成足以造成损坏的事情(至少不是在该单台计算机范围之外的永久损坏) )。

您已经知道所有这些;这就是为什么您要保护应用程序代码的原因。但是,这是第一个问题。混淆工具会使代码变得一团糟,以供人们尝试挖掘,但是程序仍然必须运行;这意味着应用程序及其使用的数据的实际逻辑流不受混淆的影响。有了一点坚韧性,攻击者就可以简单地对代码进行混淆处理,而在某些情况下,即使他所寻找的只是他所寻找的东西,这甚至不是必需的。

相反,您应该尝试确保攻击者无论对代码进行清晰的复制有多么容易,都无法对您的代码执行任何操作。这意味着,没有硬编码的秘密,因为一旦代码离开您开发它的建筑物,这些秘密就不是秘密了。

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

考虑以下方案。用户将他们的应用凭据从内存输入到设备中。不幸的是,您必须相信键盘记录器或Trojan尚未损害用户的设备。在这方面,您可以做的最好的事情是通过记住与用户使用的设备(MAC / IP,IMEI等)有关的伪造的识别信息,并通过提供至少一个附加通道来实现多因素安全性。可以验证不熟悉的设备上的登录尝试。

一旦输入了凭据,客户端软件就会对其进行混淆(使用安全哈希),并丢弃纯文本凭据。他们达到了目的。混淆的凭证通过安全通道发送到经过证书验证的服务器,该服务器再次对其进行哈希处理以生成用于验证登录有效性的数据。这样,客户端永远不知道实际与数据库值进行比较,应用服务器永远不知道其收到的用于验证的背后的明文凭证,数据服务器永远都不知道其存储的用于验证的数据是如何产生的,即使安全通道遭到破坏,中间人也只会看到乱码。

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

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

现在,攻击者想要的计算机是您的服务器,因为它而不是客户端应用程序/设备是可以使他赚钱或使其他人痛苦的事情。没关系; 与尝试保护所有客户端相比,花费更多的金钱和精力来确保服务器的安全性比您得到的高得多。该服务器可以位于各种防火墙和其他电子安全保护之后,并且还可以在钢,混凝土,钥匙卡/密码访问和24小时视频监控之后进行物理保护。攻击者的确需要非常复杂才能直接获得对服务器的任何访问权,并且(应该)立即知道它。

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


1
完美的答案!我只是喜欢用某种加密令牌从服务器获取数据的方式,在那之后我几乎无法解码。
dharam

我知道这有点晚了,但是访问服务器部分呢。像Microsoft azure这样的服务为您提供了访问服务器的类似服务:MobileServiceClient mClient = new MobileServiceClient(“ MobileServiceUrl”,//替换为上面的站点URL“ AppKey”,//替换为Application Key this)和几乎所有有权访问可以访问其服务器端的文件进行编辑
edwinj

@edwinj-计算机科学中没有其他层无法解决的问题。您的代码段提供了访问Azure移动客户端服务的基本思路;它提供了针对Microsoft前门“偷渡”的基本安全级别。您可以依次添加其他层,例如在任何服务调用上都需要会话密钥(基本上是加密令牌),并且要获取该密钥,它们必须首先结合凭据和加密方案的知识进行身份验证。
KeithS

1
最好的答案之一。
debo.stackoverflow

64

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

这不可能

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

当某人将.apk扩展名更改为.zip时,然后在解压缩后,某人可以轻松获取所有资源(Manifest.xml除外),但是使用APKtool可以获取清单文件的真实内容。再次,没有。

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

再说一次,不是,但是您可以在一定程度上阻止,

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

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


7
@TrevorBoydSmith:当操作系统是开源且可植根时,加密没有太大帮助。系统需要一个密钥才能解密APK并运行内容。如果系统具有密钥,并且我可以不受限制地访问系统,那么我知道在哪里可以找到密钥并可以找到它。意思是我现在也有钥匙
cHao 2012年

4
@TrevorBoydSmith:但是,这是“如何做”的部分,这扼杀了整个想法。根本没有办法直接执行加密的代码。在某些时候,解密后的代码必须可用。这意味着(1)必须有一个密钥(我作为root可能可以访问),并且(2)我什至可以在RAM中找到明文副本,而不必担心加密。
cHao 2012年

3
@TrevorBoydSmith:问题是,在这种情况下,您根本无法提高成本以至于不值得。这里我们不是在谈论强行密钥。我们正在谈论已经拥有它们-操作系统必须具有密钥,而我们拥有操作系统。修复该问题的唯一方法是使操作系统不可root。祝你好运;甚至苹果也无法管理它。:)
cHao 2013年

3
@TrevorBoydSmith:我不认为一般不会提高成本。我认为(尤其是说)您的建议是不可能的-因为它是。MATLAB不是Android,并且具有Android所没有的某些自由。特别是,它具有混淆性。隐藏加密密钥要困难得多。Android无法做到这一点。拥有源代码的任何人都将知道键的隐藏位置,并拥有在宣布该功能后的10分钟内可以检索它们的工具。不仅有可能做到这一点;这简直是微不足道的
cHao 2013年

6
@TrevorBoydSmith:我没有坚持任何要求。我坚持认为静态,变化,移动等都没有关系。在开源操作系统中,仅加密不能保护代码免受任何可能对其进行反向工程的人的攻击。因为我可以读取执行解密的代码,而不管密钥的获取,使用和/或存储方式如何,所以我可以看到您是如何完成并复制密钥的,这比我扭转某些超级秘密要容易得多应用程式码。
cHao 2013年

37

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

  1. 使用ProGuard混淆应用程序代码

  2. 使用使用C和C ++的NDK将您的应用程序核心和安全的部分代码存储在文件中.so

  3. 为确保资源安全,请不要在APK中的资产文件夹中包含所有重要资源。在应用程序首次启动时下载这些资源。


7
第三,确实是减轻了攻击者的工作。嗅探网络通信比逆向工程容易。
totten

为了解决第三个问题,可以对下载的内容进行加密和/或使用加密的连接(例如SSL / TLS)
Stradivari

1
加密连接可以防止人们嗅探或修改流量。如果用户本人是恶意的(即,他拥有您的apk并试图对其进行破解),他仍然会通过使用您的应用程序来获取内容,并以root用户身份提取资源;但是可以,它确实有助于抵御简单的嗅探攻击。
Kevin Lee

补充说明:4)使用dexguard进行更高程度的混淆,但需要付费5)在下载应用程序时使用OBB文件进行资产下载,这也将有助于减小应用程序的大小
Ashok Kumar,

35

开发人员可以采取以下步骤以某种方式防止APK被盗,

  • 最基本的方法是使用诸如ProGuard混淆代码之类的工具,但是直到现在,要完全阻止某人对应用程序进行反编译还是相当困难的。

  • 我也听说过一个工具HoseDex2Jar。它会Dex2Jar通过在Android APK中插入无害的代码来停止操作,Dex2Jar该代码会混淆并禁用和保护代码免于反编译。它可能以某种方式阻止黑客将APK反编译为可读的Java代码。

  • 仅在需要时才使用某些服务器端应用程序与该应用程序进行通信。它可以帮助防止重要数据。

根本无法完全保护代码免受潜在黑客的攻击。不知何故,对于他们来说,使它们反编译您的代码可能会很困难且令人沮丧。最有效的方法之一是用本机代码(C / C ++)编写并将其存储为已编译的库。


3
HoseDex2Jar几乎没有用。它只会“混淆” dex2jar,并且很容易被阻止。smali / apktool等可以与“托管” APK正常工作。
Nikolay Elenkov 2012年

@NikolayElenkov您知道HoseDex2Jar的工作原理吗?他们用来避免或混淆dex2jar的原因。因为我无法将apk文件上传到Web上以使用HoseDex2Jar。如果我可以做类似HoseDex2Jar的操作来混淆dex2jar,那么使用dex2jar工具很难破解。
sachin003

1
也许您误会了我的观点:HoseDex2Jar所做的就是重新打包您的APK,以便流行的dex2jar工具无法(开箱即用)将其反转。但是其他工具也可以,并且很容易将其击败。使用它没有意义。没有人提到Dexguard I(ProGuard的作者;不是免费的),但这是正在研究的工作。它比“常规”混淆要多得多。
Nikolay Elenkov 2012年

C ++永远无法逆转?这很困难,但可能。并提供了诸如hex-rays.com/products/decompiler/index.shtml之类的工具来帮助您(是的,它们具有ARM版本。不是那么容易获得)。
dkzm

是的,@ VikartiAnatra:我也提到过不知何故,您可能会遇到困难
Sahil Mahajan Mj

24

您可以尝试以下几种方法:

  1. 使用混淆ProGuard之类的工具。
  2. 加密部分源和数据。
  3. 在应用程序中使用专有的内置校验和来检测篡改。
  4. 引入代码以避免加载到调试器中,也就是说,使应用程序能够检测到调试器并退出/终止调试器。
  5. 将身份验证与在线服务分开。
  6. 使用应用程序多样性
  7. 在对设备进行身份验证之前,请使用指纹技术对来自不同子系统的设备进行硬件签名。

23

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

不可能

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

不可能

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

更严格-可能,但实际上,对于普通用户(他们只是在搜寻黑客指南),这将更加困难。如果有人真的想入侵您的应用-迟早会被入侵。


22

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

那是不可能的

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

开发人员可以采取诸如使用ProGuard之类的工具来混淆其代码的步骤,但是直到现在,要完全阻止某人对应用程序进行反编译还是很困难的。

这是一个非常不错的工具,可以增加“反转”代码的难度,同时减少代码的占用空间。

集成的ProGuard支持:ProGuard现在与SDK工具打包在一起。开发人员现在可以将其代码混淆为发行版本的集成部分。

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

在研究时,我了解了HoseDex2Jar。该工具将保护您的代码免于反编译,但是似乎无法完全保护您的代码。

一些有用的链接,您可以参考它们。


21

这里的主要问题是dex文件可以反编译吗,答案是它们可以是“某种”的。有诸如dedexersmali之类的反汇编程序

正确配置的ProGuard会混淆您的代码。DexGuard是ProGuard的商业扩展版本,可能会提供更多帮助。但是,您的代码仍然可以转换为smali,具有逆向工程经验的开发人员将能够从smali弄清楚您在做什么。

也许选择一个好的许可证,并通过法律以最佳方式执行它。


4
附带说明(免责声明:IANAL)-许可证在所有情况下都不会在所有司法管辖区保护应用程序(例如,在欧洲的某些国家,为提高兼容性,允许对其进行拆装)。
Maciej Piechotka

12

您的客户应聘请知道自己在做什么的人,他们可以做出正确的决定并可以指导您。

上面谈论您具有在后端更改事务处理系统的能力是荒谬的-不应允许您进行此类体系结构更改,因此不要指望能够这样做。

我的理由是:

由于您的域是付款处理,因此可以安全地假设PCI DSS和/或PA DSS(以及潜在的州/联邦法律)对您的业务至关重要-要符合规定,您必须证明自己是安全的。为了不安全,然后(通过测试)找出您不安全的情况,然后进行修复,重新测试等,直到可以以适当的级别验证安全性=成功,昂贵,缓慢,高风险的方式为止。要做正确的事情,要三思而后行,将经验丰富的人才投入工作,以安全的方式发展,然后进行测试,修复(少)等(少),直到可以在适当的水平上验证安全性为止–廉价,快速,低风险的成功之道。


8

作为在包括一个移动支付应用程序(MyCheck)在内的支付平台上广泛工作的人,我想说,您需要将此行为委派给服务器,因此,不应存储支付处理器(无论是哪个)的用户名或密码或在移动应用程序中进行硬编码,这是您想要的最后一件事,因为即使混淆了代码,也可以理解源。

同样,您不应该在应用程序上存储信用卡或支付令牌,应将所有内容再次委派给您构建的服务,它也将使您日后更轻松地与PCI兼容,并且信用卡公司赢得了不要垂下脖子(就像他们为我们所做的那样)。


7

此处其他建议的答案是正确的。我只想提供另一种选择。

对于某些您认为重要的功能,可以在应用程序中托管WebView控件。然后,该功能将在您的Web服务器上实现。看起来它正在您的应用程序中运行。


@Sarel Botha是对于IMP屏幕,我已经使用过webview,是的,这也是维护安全性的一种方法,我接受您的回答。
sachin003

7

如果我们想使逆向工程(几乎)成为不可能,则可以将应用程序放在高度防篡改的芯片上,该芯片在内部执行所有敏感内容,并与某种协议进行通信以使在主机上进行GUI的控制成为可能。即使是防篡改芯片也不是100%防裂的。他们只是设定了比软件方法高得多的标准。当然,这很不方便:应用程序需要一些USB适配器,以将芯片插入设备。

这个问题并没有揭示出如此嫉妒地保护该应用程序的动机。

如果目的是通过隐藏应用程序可能存在的任何安全漏洞(已知或其他)来提高付款方式的安全性,则完全是错误的做法。如果可行,安全敏感位实际上应该是开源的。对于审查您的应用程序的任何安全研究人员,您应该尽可能轻松地找到这些位并仔细检查其操作并与您联系。付款应用程序不应包含任何嵌入式证书。就是说,不应有仅仅因为设备具有来自工厂的固定证书而信任设备的服务器应用程序。应当使用正确设计的端到端身份验证协议仅在用户凭据上进行付款交易,该协议不信任应用程序,平台或网络等。

如果目的是防止克隆(缺少防篡改芯片),那么您将无法采取任何措施来保护程序免受逆向工程和复制,从而使某人将兼容的付款方式集成到自己的应用程序中,从而上升为“未经授权的客户”。有多种方法使开发未经授权的客户变得困难。一种方法是根据程序完整状态的快照创建校验和:所有状态变量都适用于所有内容。GUI,逻辑等。克隆程序不会具有完全相同的内部状态。当然,它是一个状态机,具有类似的外部可见状态转换(可以通过输入和输出观察到),但是几乎没有相同的内部状态。服务器应用程序可以询问该程序:您的详细状态是什么?(即 给我所有内部状态变量的校验和)。可以将其与在真实状态转换中并行在服务器上执行的虚拟客户端代码进行比较。第三方克隆将必须复制正版程序的所有相关状态更改,以便给出正确的响应,这将妨碍其开发。


7

在这里与@Muhammad Saqib达成协议:https ://stackoverflow.com/a/46183706/2496464

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

始终可以安全地假设您分发给用户设备的所有内容均属于该用户。干净利落。您也许可以使用最新的工具和过程来加密您的知识产权,但是无法阻止确定的人“研究”您的系统。即使当前的技术可能使他们难以获得不需要的访问权限,明天或什至下一个小时也可能有一些简单的方法!

因此,方程式如下:

When it comes to money, we always assume that client is untrusted.

即使是简单的游戏内经济。(特别是在游戏中!那里有更多“老练”的用户,漏洞在几秒钟内扩散!)

我们如何保持安全?

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



4

Android N中的APK签名方案v2

PackageManager类现在支持使用APK签名方案v2验证应用。APK签名方案v2是一种全文件签名方案,可通过检测对APK文件的任何未经授权的更改来显着提高验证速度并增强完整性保证。

为了保持向后兼容性,必须先使用v1签名方案(JAR签名方案)对APK进行签名,然后再使用v2签名方案进行签名。使用v2签名方案时,如果在使用v2方案签名后使用其他证书对APK进行签名,则验证将失败。

APK签名方案v2支持将在N Developer Preview中稍后提供。

http://developer.android.com/preview/api-overview.html#apk_signature_v2


2
Apk签名v2仅可防止资源被篡改,但不会使反向工程变得更加困难……
Louis CAD

1
此外,您可以删除签名并重新签名。v2签名只是APK文件中的一个数据块。
罗伯特

4

无法完全避免对APK进行反向工程。为了保护应用程序资产,资源,可以使用加密。

  • 如果不进行解密,加密将更难使用。选择一些强大的加密算法将使破解更加困难。
  • 在您的主要逻辑中添加一些欺骗代码,使破解难度更大。
  • 如果您可以用任何本机语言编写关键逻辑,那肯定会使反编译更加困难。
  • 使用任何第三方安全框架,例如Quixxi

3

基本上是不可能的。这将永远不可能。但是,有希望。您可以使用混淆器来使它变得模糊,因此一些常见的攻击要难得多,包括:

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

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

但是,混淆总是要付出代价的。值得注意的是,性能通常会更差,并且通常需要在发布周围花费一些额外的时间。但是,如果您的知识产权对您极为重要,那么通常值得。

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

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


不幸的是,如果有人入侵客户端(应用程序),他们将能够看到通信格式并创建自己的服务器:(
Jocky Doe

3

不可能完全避免RE,但是通过使其内部更加复杂,您可以使攻击者更难以看到应用程序的清晰运行,从而减少了攻击媒介的数量。

如果应用程序处理高度敏感的数据,则存在各种技术,这些技术可能会增加对代码进行反向工程的复杂性。一种技术是使用C / C ++来限制攻击者容易的运行时操纵。有很多C和C ++库,它们非常成熟并且易于与Android提供的JNI集成。攻击者必须首先规避调试限制,才能以较低的级别攻击应用程序。这进一步增加了攻击的复杂性。Android应用程序应在应用程序清单中设置android:debuggable =“ false”,以防止攻击者或恶意软件轻松地运行时进行操作。

跟踪检查 –应用程序可以确定调试器或其他调试工具当前是否正在跟踪它。如果被跟踪,则应用程序可以执行任何数量的可能的攻击响应操作,例如丢弃保护用户数据的加密密钥,通知服务器管理员或其他此类类型的响应,以试图保护自己。这可以通过检查进程状态标志或使用其他技术来确定,例如比较ptrace附加的返回值,检查父进程,进程列表中的黑名单调试器或比较程序不同位置的时间戳。

优化 -若要隐藏高级数学计算和其他类型的复杂逻辑,利用编译器优化可以帮助混淆目标代码,从而使攻击者不容易对其进行反汇编,从而使攻击者更难理解特定代码。在Android中,可以通过NDK使用本机编译的库来更轻松地实现这一点。此外,使用LLVM混淆器或任何保护器SDK将提供更好的机器代码混淆。

剥离二进制文件 -剥离本机二进制文件是增加攻击者所需的时间和技能水平的一种有效方法,以便查看应用程序的低级功能的构成。通过剥离二进制文件,将剥离二进制文件的符号表,以使攻击者无法轻松调试或反向工程应用程序。您可以参考在GNU / Linux系统上使用的技术,例如剥离或使用UPX。

最后,您必须了解混淆和ProGuard之类的工具。


3

如果您的应用程序对此敏感,则应考虑在服务器端进行付款处理。尝试更改您的付款处理算法。仅将Android应用程序用于收集和显示用户信息(即帐户余额),而不是使用Java代码处理付款,而是使用带有加密参数的安全SSL协议将此任务发送到您的服务器。创建完全加密和安全的API以与您的服务器通信。

当然,它也可以被黑客入侵,它与源代码保护无关,但可以认为它是另一个安全层,使黑客更难于欺骗您的应用程序。


2

TPM芯片(可信平台模块)不是应该为您管理受保护的代码吗?它们在PC(尤其是Apple的PC)上变得越来越普遍,并且它们可能已经存在于当今的智能手机芯片中。不幸的是,尚无OS API可以使用它。希望Android会在这一天增加支持。这也是清除内容DRM(Google正在为WebM进行处理)的关键。


2

当您将其放在最终用户手上时,没有什么是安全的,但是一些常规做法可能会使攻击者更难窃取数据。

  • 将您的主要逻辑(算法)放入服务器端。
  • 与服务器和客户端通信;确保通过SSL或HTTPS保护黑白服务器和客户端之间的通信;或使用其他技术的密钥对生成算法(ECC,RSA)。确保敏感信息保持端到端加密。
  • 使用会话,并在特定时间间隔后使它们过期。
  • 加密资源并按需从服务器获取它们。
  • 或者,您也可以通过webview在服务器上保护资源和代码来制作可访问系统的Hybrid应用

多种方法;很明显,您必须在性能安全性之间做出牺牲


2

我可以在该线程中看到一个好的答案。除了可以使用facebook redex来优化代码。Redex .dex在proguard作为.class级别的级别上工作。



1

如何保护应用程序的所有资源,资产和源代码,以使黑客无法以任何方式对APK文件进行黑客攻击?

APK文件受SHA-1算法保护。您可以在APK 的META-INF文件夹中看到一些文件。如果您提取任何APK文件并更改其任何内容,然后再次将其压缩,则当您在Android机器上运行该新APK文件时,该文件将不起作用,因为SHA-1哈希值将永远不匹配。


这是真的; 但辞职APK(使用不同的证书)是微不足道的,一切都会再次生效。可以从应用程序内部检查使用了哪个签名对APK进行签名,并在证书更改的情况下出错,但从应用程序中编辑此代码的琐事要少得多。
大卫

这可能会阻止android设备运行修改后的代码,但是您仍然可以轻松提取相关代码,并在需要执行操作的PC上编写新代码。
Sarel Botha 2014年


1

工具:在您的应用程序中使用Proguard可以限制对应用程序进行反向工程


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.