提问人:sachin003 提问时间:12/13/2012 最后编辑:Peter Mortensensachin003 更新时间:11/17/2021 访问量:265192
如何避免对APK文件进行逆向工程
How to avoid reverse engineering of an APK file
问:
我正在开发一款适用于 Android 的支付处理应用程序,我想防止黑客访问 APK 文件中的任何资源、资产或源代码。
如果有人将 .apk 扩展名更改为 .zip,那么他们可以解压缩它并轻松访问应用程序的所有资源和资产,并且使用 dex2jar 和 Java 反编译器,他们还可以访问源代码。对 Android APK 文件进行逆向工程非常容易 - 有关更多详细信息,请参阅 Stack Overflow 问题:从 APK 文件到项目的逆向工程。
我使用了 Android SDK 随附的 Proguard 工具。当我对使用签名密钥库和 Proguard 生成的 APK 文件进行逆向工程时,我得到了混淆的代码。
但是,Android 组件的名称保持不变,某些代码(例如应用中使用的键值对)保持不变。根据 Proguard 文档,该工具无法对 Manifest 文件中提到的组件进行模糊处理。
现在我的问题是:
- 如何完全防止对 Android APK 进行逆向工程?这可能吗?
- 如何保护应用程序的所有资源、资产和源代码,以便黑客无法以任何方式破解 APK 文件?
- 有没有办法让黑客攻击变得更加困难甚至不可能?我还能做些什么来保护我的APK文件中的源代码?
答:
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. 如何完全避免对Android APK进行逆向工程?这可能吗?
不可能的
2. 如何保护应用程序的所有资源、资产和源代码,以便黑客无法以任何方式破解 APK 文件?
不可能的
3. 有没有办法让黑客攻击变得更加困难甚至不可能?我还能做些什么来保护我的APK文件中的源代码?
更难 - 可能,但实际上,对于普通用户来说,这将更加艰难,他们只是在谷歌上搜索黑客指南。如果有人真的想破解你的应用程序 - 它迟早会被黑。
100% 避免对 Android APK 进行逆向工程是不可能的,但您可以使用以下方法来避免提取更多数据,例如源代码、APK 中的资产和资源:
使用 ProGuard 对应用程序代码进行模糊处理
使用 NDK 使用 C 和 C++ 将应用程序核心和安全部分代码放入文件中
.so
要保护资源,请勿将所有重要资源都包含在 APK 的 assets 文件夹中。在应用程序首次启动时下载这些资源。
评论
AFAIK,您不能再保护 /res 目录中的文件,因为它们现在受到保护。
但是,您可以采取一些步骤来保护您的源代码,或者至少保护它的作用(如果不是所有)。
- 使用 ProGuard 等工具。这些会混淆您的代码,并在反编译时使其更难阅读,如果不是不可能的话。
- 将服务中最关键的部分移出应用程序,并移入隐藏在 PHP 等服务器端语言后面的 Web 服务中。例如,如果你有一个算法,花了你一百万美元来编写。您显然不希望人们将其从您的应用程序中窃取。移动算法并让它在远程服务器上处理数据,然后使用该应用程序简单地为其提供数据。或者使用 NDK 将它们本地写入 .so 文件,这些文件比 apk 被反编译的可能性要小得多。我认为到目前为止,甚至不存在 .so 文件的反编译器(即使存在,它也不会像 Java 反编译器那样好)。此外,正如评论中@nikolay提到的,在服务器和设备之间交互时,您应该使用 SSL。
- 在设备上存储值时,请勿以原始格式存储它们。例如,如果您有一个游戏,并且您要在 SharedPreferences 中存储用户拥有的游戏货币数量。让我们假设它是硬币。与其直接保存,不如使用类似 的算法保存它。因此,您保存到 SharedPreferences 中,而不是 。然而,上面的例子并不完美,你必须努力想出一个不会因舍入错误等而失去货币的方程式。
10000
10000
((currency*2)+1)/13
10000
1538.53846154
- 您可以对服务器端任务执行类似的操作。现在举个例子,让我们实际使用您的支付处理应用程序。假设用户必须支付 .与其将原始值发送到服务器,不如发送一系列较小的预定义值,这些值加起来为 .例如,在服务器上有一个文件或表,将单词等同于值。因此,假设对应于 和 。因此,您可以发送四次和四次,而不是发送。在服务器上,解释它们的含义并将其相加。这可以防止黑客向您的服务器发送任意值,因为他们不知道哪个单词对应于什么值。作为额外的安全措施,您也可以为此设置一个类似于第 3 点的等式,并每隔几天更改关键字。
$200
$200
$200
Charlie
$47
John
$3
$200
Charlie
John
n
- 最后,您可以将随机无用的源代码插入到您的应用程序中,以便黑客大海捞针。插入包含来自 Internet 的片段的随机类,或者仅插入用于计算随机事物(如斐波那契数列)的函数。请确保这些类已编译,但未由应用的实际功能使用。添加足够多的这些虚假类,黑客将很难找到您的真实代码。
总而言之,没有办法 100% 保护您的应用程序。你可以让它变得更难,但并非不可能。您的 Web 服务器可能会受到威胁,黑客可以通过监控多个交易金额和您为其发送的关键字来找出您的关键字,黑客可能会煞费苦心地浏览源代码并找出哪些代码是虚拟的。
你只能反击,但永远赢不了。
评论
.so
这里的主要问题是 dex 文件是否可以反编译,答案是它们可以“有点”。有像 dedexer 和 smali 这样的反汇编器。
正确配置的 ProGuard 将对您的代码进行混淆处理。DexGuard 是 ProGuard 的商业扩展版本,可能会提供更多帮助。但是,您的代码仍然可以转换为 smali,具有逆向工程经验的开发人员将能够从 smali 中弄清楚您在做什么。
也许选择一个好的许可证,并以最好的方式依法执行。
评论
1. 如何完全避免对Android APK进行逆向工程?这可能吗?
这是不可能的
2. 如何保护应用程序的所有资源、资产和源代码,以便黑客无法以任何方式破解 APK 文件?
当有人将 .apk 扩展名更改为 .zip 时,解压缩后,有人可以轻松获取所有资源(Manifest.xml 除外),但使用 APKtool 也可以获取清单文件的真实内容。再次,不。
3. 有没有办法让黑客攻击变得更加困难甚至不可能?我还能做些什么来保护我的APK文件中的源代码?
同样,不,但您可以防止到某种程度,即,
即使使用 ,人们也可以玩弄您的代码。总而言之,这是不可能的。Smali
评论
在计算史上,从来没有人能够阻止软件的逆向工程,因为你将软件的工作副本提供给你的攻击者。此外,最有可能的是,这永远是不可能的。
了解了这一点,有一个明显的解决方案:不要把你的秘密交给你的攻击者。虽然您无法保护 APK 的内容,但您可以保护的是您不分发的任何内容。通常,这是用于激活、支付、规则执行和其他多汁代码等操作的服务器端软件。您可以通过不在 APK 中分发有价值的资产来保护它们。相反,请设置一个服务器来响应来自应用的请求,“使用”资产(无论这可能意味着什么),然后将结果发送回应用。如果这个模型不适用于你心目中的资产,那么你可能需要重新考虑你的策略。
此外,如果您的主要目标是防止应用程序盗版:甚至不要打扰。你已经在这个问题上花费了更多的时间和金钱,超过了任何反盗版措施可能希望拯救你的时间。解决这个问题的投资回报率如此之低,以至于连想都没意义。
评论
我建议你看看保护软件应用程序免受攻击。这是一项商业服务,但我朋友的公司使用了它,他们很高兴使用它。
您的客户应该聘请知道自己在做什么、可以做出正确决定并可以指导您的人。
上面说你有能力改变后端的事务处理系统是荒谬的——你不应该被允许进行这样的架构改变,所以不要指望能够做到。
我对此的理由:
由于您的域名是支付处理,因此可以安全地假设 PCI DSS 和/或 PA DSS(以及潜在的州/联邦法律)将对您的业务产生重要影响 - 为了合规,您必须证明您是安全的。要不安全,然后(通过测试)发现你不安全,然后修复、重新测试等,直到安全性可以在合适的水平上得到验证=昂贵、缓慢、高风险的成功方式。要做正确的事情,前期要认真思考,让有经验的人才投入到工作中,以安全的方式进行开发,然后测试、修复(更少)等(更少),直到安全性可以在合适的水平上得到验证=廉价、快速、低风险的成功方式。
基本上这是不可能的。这永远不可能。但是,还是有希望的。您可以使用混淆器来制作它,因此一些常见的攻击更难执行,包括:
- 重命名方法/类(因此在反编译器中,您可以获得类似
a.a
) - 混淆控制流(因此在反编译器中,代码很难阅读)
- 加密字符串和可能的资源
我敢肯定还有其他的,但这是主要的。我在一家名为PreEmptive Solutions的公司工作,该公司使用.NET混淆器。他们还有一个适用于 Android 的 Java 混淆器,以及一个名为 DashO 的混淆器。
不过,混淆总是有代价的。值得注意的是,性能通常较差,并且通常需要一些额外的时间来发布。但是,如果您的知识产权对您来说非常重要,那么这通常是值得的。
否则,您唯一的选择是让您的 Android 应用程序直接传递到托管应用程序所有实际逻辑的服务器。这有其自身的问题,因为这意味着用户必须连接到 Internet 才能使用您的应用程序。
此外,不仅仅是 Android 有这个问题。这是每个应用商店的问题。这只是获取包文件的难度问题(例如,我认为在 iPhone 上并不容易,但仍有可能)。
评论
应用安全的第一条规则:攻击者获得不受限制的物理或电子访问权限的任何计算机现在都属于攻击者,无论它实际位于何处或您为此付出了什么。
应用安全的第二条规则:任何离开攻击者无法渗透的物理边界的软件现在都属于攻击者,无论您花了多少时间对其进行编码。
第三条规则:任何离开攻击者无法穿透的物理边界的信息现在都属于攻击者,无论它对您有多大价值。
信息技术安全的基础基于这三个基本原则;唯一真正安全的计算机是锁在保险箱里的那台,在法拉第笼子里,在钢笼子里。有些计算机的大部分使用寿命都是在这种状态下度过的;他们每年(或更少)为受信任的根证书颁发机构生成私钥(在许多证人面前,摄像机记录他们所在的房间的每一寸)。
现在,大多数计算机不在这些类型的环境中使用;它们在户外,通过无线电信道连接到互联网。简而言之,他们很脆弱,他们的软件也是如此。因此,他们不值得信任。计算机及其软件必须知道或做某些事情才能有用,但必须注意确保它们永远不会知道或做足以造成损害的事情(至少不会造成超出该台机器范围的永久性损害)。
你已经知道这一切了;这就是您尝试保护应用程序代码的原因。但是,这就是第一个问题;混淆工具可以使代码变得一团糟,供人类尝试挖掘,但程序仍然必须运行;这意味着应用程序的实际逻辑流及其使用的数据不受混淆的影响。只要有一点毅力,攻击者就可以简单地对代码进行混淆,在某些情况下,这甚至没有必要,因为他所看到的只能是他正在寻找的东西。
相反,您应该尝试确保攻击者无法对您的代码执行任何操作,无论他多么容易获得代码的清晰副本。这意味着,没有硬编码的机密,因为一旦代码离开你开发它的建筑物,这些机密就不是机密了。
您硬编码的这些键值对应从应用程序的源代码中完全删除。相反,它们应该在三个地方之一;设备上的易失性内存,攻击者更难(但仍然不可能)获取脱机副本;永久在服务器集群上,您可以用铁腕控制对它的访问;或者在与设备或服务器无关的第二个数据存储中,例如物理卡或用户内存中(这意味着它最终会位于易失性内存中,但不必持续很长时间)。
请考虑以下方案。用户将应用的凭据从内存输入到设备中。不幸的是,您必须相信用户的设备尚未受到键盘记录器或特洛伊木马的破坏;在这方面,您能做的最好的事情是实现多因素安全性,通过记住有关用户使用的设备(MAC/IP、IMEI 等)的难以伪造的识别信息,并提供至少一个额外的通道来验证在不熟悉设备上的登录尝试。
输入凭据后,客户端软件(使用安全哈希)会对其进行模糊处理,纯文本凭据将被丢弃;他们已经达到了他们的目的。经过模糊处理的凭据通过安全通道发送到经过证书身份验证的服务器,服务器再次对它们进行哈希处理,以生成用于验证登录有效性的数据。这样一来,客户端永远不知道实际与数据库值相比的内容,应用服务器永远不知道它收到的用于验证的内容背后的明文凭据,数据服务器永远不知道它存储的用于验证的数据是如何生成的,而中间的人即使安全通道遭到破坏,也只能看到胡言乱语。
验证后,服务器会通过通道传回令牌。令牌仅在安全会话中有用,由随机噪声或会话标识符的加密(因此可验证)副本组成,并且客户端应用程序必须将同一通道上的此令牌发送到服务器,作为执行某些操作的任何请求的一部分。客户端应用程序会多次执行此操作,因为它不能执行任何涉及金钱、敏感数据或其他任何可能本身造成损害的事情;相反,它必须要求服务器执行此任务。客户端应用程序绝不会将任何敏感信息写入设备本身的持久内存,至少不会以纯文本形式写入;客户端可以通过安全通道向服务器请求对称密钥,以加密服务器将记住的任何本地数据;在以后的会话中,客户端可以要求服务器提供相同的密钥来解密数据,以便在易失性内存中使用。这些数据也不会是唯一的副本;客户端存储的任何内容也应以某种形式传输到服务器。
显然,这使得您的应用程序严重依赖 Internet 访问;如果没有与服务器的正确连接和身份验证,客户端设备将无法执行其任何基本功能。真的,和Facebook没什么不同。
现在,攻击者想要的计算机是您的服务器,因为它而不是客户端应用程序/设备是可以使他赚钱或为他人带来痛苦的东西。没关系;与尝试保护所有客户端相比,花费金钱和精力来保护服务器,您会获得更多的收益。服务器可以位于各种防火墙和其他电子安全后面,此外还可以在钢、混凝土、钥匙卡/密码访问和 24 小时视频监控后面进行物理保护。您的攻击者确实需要非常老练才能直接访问服务器,并且您将(应该)立即知道它。
攻击者能做的最好的事情就是窃取用户的电话和凭据,并使用客户端的有限权限登录服务器。如果发生这种情况,就像丢失信用卡一样,应指示合法用户拨打 800 号码(最好易于记忆,而不是在他们随身携带的钱包、钱包或公文包的卡背面,这些号码可能与移动设备一起被盗)从他们可以访问的任何电话直接连接到您的客户服务。他们声称他们的手机被盗,提供了一些基本的唯一标识符,并且帐户被锁定,攻击者可能能够处理的任何交易都被回滚,攻击者又回到了原点。
评论
这里的其他赞成答案是正确的。我只想提供另一种选择。
对于你认为重要的某些功能,可以在应用中托管 WebView 控件。然后,该功能将在您的 Web 服务器上实现。它看起来像是在应用程序中运行。
评论
如果我们想使逆向工程(几乎)不可能,我们可以将应用程序放在一个高度防篡改的芯片上,该芯片在内部执行所有敏感内容,并与某些协议进行通信,以便在主机上控制 GUI。即使是防篡改芯片也不是 100% 防裂的;他们只是将标准设定得比软件方法高得多。当然,这很不方便:该应用需要一些小USB电源适配器来固定要插入设备的芯片。
这个问题并没有揭示想要如此嫉妒地保护此应用程序的动机。
如果目的是通过隐藏应用程序可能存在的任何安全漏洞(已知或其他)来提高支付方式的安全性,那么它就完全是错误的。如果可行,安全敏感位实际上应该是开源的。您应该让任何审查您的应用程序的安全研究人员尽可能轻松地找到这些位并仔细检查其操作,并与您联系。付款应用程序不应包含任何嵌入式证书。也就是说,不应该有服务器应用程序仅仅因为设备具有工厂的固定证书而信任它。支付交易应仅根据用户的凭据进行,使用正确设计的端到端身份验证协议,该协议排除了对应用程序、平台或网络等的信任。
如果目的是防止克隆,那么除了防篡改芯片之外,您就无法采取任何措施来保护程序不被逆向工程和复制,从而使某人将兼容的支付方式合并到他们自己的应用程序中,从而产生“未经授权的客户端”。有一些方法可以使开发未经授权的客户端变得困难。一种是根据程序完整状态的快照创建校验和:所有状态变量,用于所有内容。GUI,逻辑,等等。克隆程序不会具有完全相同的内部状态。当然,它是一个状态机,具有相似的外部可见状态转换(可以通过输入和输出观察到),但内部状态几乎相同。服务器应用程序可以询问程序:您的详细状态是什么?(即给我一个你所有内部状态变量的校验和)。这可以与在服务器上并行执行的虚拟客户端代码进行比较,这些代码会经历真正的状态转换。第三方克隆必须复制正版程序的所有相关状态更改才能给出正确的响应,这将阻碍其开发。
1. 如何完全避免对Android APK进行逆向工程?这可能吗?
这是不可能的
2. 如何保护应用程序的所有资源、资产和源代码,以便黑客无法以任何方式破解 APK 文件?
开发人员可以采取一些步骤,例如使用 ProGuard 等工具来混淆他们的代码,但到目前为止,要完全阻止某人反编译应用程序是相当困难的。
这是一个非常棒的工具,可以增加“反转”代码的难度,同时缩小代码的占用空间。
集成 ProGuard 支持:ProGuard 现在与 SDK 工具打包在一起。开发人员现在可以将其代码作为发布版本的集成部分进行模糊处理。
3. 有没有办法让黑客攻击变得更加困难甚至不可能?我还能做些什么来保护我的APK文件中的源代码?
在研究过程中,我开始了解 HoseDex2Jar。此工具将保护您的代码免于反编译,但似乎无法完全保护您的代码。
一些有用的链接,您可以参考它们。
- Proguard、Android 和许可服务器
- 保护 Android LVL 应用
- Stack Overflow 问题:真的不可能保护 Android 应用程序免受逆向工程吗?
- Stack Overflow 问题:如何防止对 Android APK 文件进行逆向工程以保护代码?
作为一个在支付平台上广泛工作的人,包括一个移动支付应用程序(MyCheck),我想说你需要将这种行为委托给服务器。支付处理器(无论其是谁)的用户名或密码都不应在移动应用程序中存储或硬编码。这是你最不想要的,因为即使你混淆了代码,源代码也可以被理解。
此外,您不应在应用程序上存储信用卡或支付令牌。同样,一切都应该委托给您构建的服务。它还将使您以后更容易地符合PCI标准,并且信用卡公司不会像他们为我们所做的那样让您喘不过气来。
如何保护应用程序的所有资源、资产和源代码,以便黑客无法以任何方式破解 APK 文件?
APK 文件受 SHA-1 算法保护。您可以在APK的META-INF文件夹中看到一些文件。如果您提取任何 APK 文件并更改其任何内容并再次压缩它,当您在 Android 机器上运行该新 APK 文件时,它将不起作用,因为 SHA-1 哈希永远不会匹配。
评论
您可以尝试以下几种方法:
- 使用混淆和 ProGuard 等工具。
- 加密源代码和数据的某些部分。
- 在应用程序中使用专有的内置校验和来检测篡改。
- 引入代码以避免在调试器中加载,即让应用能够检测调试器并退出/终止调试器。
- 将身份验证分离为联机服务。
- 使用应用程序多样性
- 使用指纹技术,例如,在对设备进行身份验证之前,使用来自不同子系统的设备的硬件签名。
受信任的平台模块 (TPM) 芯片不应该为你管理受保护的代码吗?
它们在 PC(尤其是 Apple PC)上变得越来越普遍,它们可能已经存在于当今的智能手机芯片中。不幸的是,目前还没有任何操作系统 API 可以使用它。希望有一天 Android 会添加对此的支持。这也是清理内容DRM的关键(Google正在为WebM开发)。
只是对上面已经很好的答案的补充。
我知道的另一个技巧是将有价值的代码存储为 Java 库。然后将该库设置为您的 Android 项目。作为 C .so 文件会很好,但 Android Lib 可以。
这样,存储在 Android 库中的这些有价值的代码在反编译后将不可见。
评论
基本上,有五种方法可以保护您的APK文件:
- 隔离 Java 程序,
- 加密类文件,
- 转换为本机代码,
- 代码混淆
- 在线加密
我建议您使用在线加密,因为它既安全又方便。你不需要花太多时间来实现这一点。
例如APK Protect。这是一个 APK 的在线加密网站。它提供了Java代码和C++代码保护,以实现反调试和反编译效果。操作过程简单易行。
评论
当他们在手机上安装该应用程序时,他们可以完全访问它的内存。因此,如果你想防止它被黑客入侵,你可以尝试让它不能直接使用调试器获取静态内存地址。如果他们有地方可以写入并且有限制,他们可能会进行堆栈缓冲区溢出。所以当他们写东西时,试着让它这样,如果你必须有一个限制,如果他们发送的字符多于限制,如果(输入>限制)然后忽略,所以他们不能把汇编代码放在那里。
不,做不到!
你的三个问题围绕着 100% 保护应用程序不被阅读。从原则上讲,这是做不到的。而且,你投入的越多,对你来说,它的体验就越差,最终,对于任何试图只读取你的应用程序的机器来说,它都会越糟糕。想想HTTPS本质上比HTTP慢得多,因为需要处理安全层和数学。层数越多,有人拆开包装的速度就越慢,但绝不是不可能的,因为你实际上希望它被阅读,这就是为什么它被制作成包装并交付的原因。
一个简单的类比是将任何给定的隐藏对象交给某人。如果那个人能看到里面的东西,他们也可以拍照并做一些完全类似的事情。更重要的是,在代码的情况下,足够敬业的人可以创建该对象的精确副本,即使使用完全不同的过程。
假安全感
作为一个处理应用程序,你不应该关心你认为你可以在二进制代码中创建的任何安全性,以及整个系统的完整性。假设来自客户端的任何内容都可能很快变得不可靠。保持应用程序简单、流畅和快速。相反,还要担心您的服务器。例如,制定严格的通信协议以轻松监控服务器。这是我们唯一可以依靠的。
现在,请继续与我讨论如何改进服务器端的另一个想法......
嘴巴在钱上
我正在开发一个支付处理应用程序
谷歌通过使用一种简单的财务方法来“保护”谷歌浏览器,在避免恶意黑客方面非常成功,我引用:
我们为参与者提供 50,000 美元的常设奖励,这些参与者可能会在访客模式下使用设备持久性来破坏 Chromebook 或 Chromebox
要真正接近 100% 的“安全性”,我们最好的选择是为我们的钱物有所值而选择正确的战斗。也许大多数人无法提供 50k 的奖励,但即使是 1k 的奖励也可以走很长的路,而且它也比将这笔钱投入到设计任何类型的错误捕手上要便宜得多。
投资人工智能来识别资金流动模式,预测潜在风险并发现小漏洞,也比试图通过任何工程来预防两者要便宜得多。
明显的例外
当然,这并不能保护我们免受“疯子”和“幸运恶作剧者”的侵害......但什么都不会。同时,如果设置得当,后一组在内部的时间很少,而系统会重新调整。而一个疯子,我们只需要担心,以防它大到足以成为克星。无论如何,这将是一个伟大的故事!:)
太长;没读过;
换句话说,也许问自己一个更好的问题,而不是“如何避免在我的应用程序中进行逆向工程”,可能是“如何设计一个更安全的支付处理系统”,并专注于你真正想要实现的目标:一个安全的系统。
很久以前,我试着写更多关于上述所有内容的文章,以回答诸如为什么我将“安全”和“保护”放在引号中(它们的真正含义是什么?
评论
完全避免逆向工程是不可能的,但通过在内部使它们更加复杂,可以使攻击者更难看到应用程序的清晰操作,这可能会减少攻击媒介的数量。
如果应用程序处理高度敏感的数据,则存在各种技术,这些技术可能会增加代码逆向工程的复杂性。一种技术是使用 C/C++ 来限制攻击者轻松操纵运行时。有大量的 C 和 C++ 库非常成熟且易于集成,Android 提供了 JNI。
攻击者必须首先规避调试限制,才能在低级别攻击应用程序。这进一步增加了攻击的复杂性。Android 应用程序应在应用程序清单中进行设置,以防止攻击者或恶意软件轻松操纵运行时。android:debuggable=”false”
跟踪检查 – 应用程序可以确定它当前是否正在被调试器或其他调试工具跟踪。如果被跟踪,应用程序可以执行任意数量的可能的攻击响应操作,例如丢弃加密密钥以保护用户数据、通知服务器管理员或其他此类类型的响应以尝试保护自身。这可以通过检查进程状态标志或使用其他技术来确定,例如比较 ptrace attach 的返回值、检查父进程、将进程列表中的调试器列入黑名单或比较程序不同位置的时间戳。
优化 - 为了隐藏高级数学计算和其他类型的复杂逻辑,利用编译器优化可以帮助混淆目标代码,使其不容易被攻击者反汇编,从而使攻击者更难理解特定代码。在 Android 中,通过利用带有 NDK 的原生编译库,可以更轻松地实现这一点。此外,使用 LLVM 混淆器或任何保护器 SDK 将提供更好的机器代码混淆。
剥离二进制文件 – 剥离本机二进制文件是增加攻击者查看应用程序低级函数构成所需的时间和技能水平的有效方法。通过剥离二进制文件,可以剥离二进制文件的符号表,以便攻击者无法轻松调试或逆向工程应用程序。您可以参考 GNU/Linux 系统上使用的技术,例如剥离或使用 UPX。
最后,您必须了解混淆和 ProGuard 等工具。
评论
当您将其放在最终用户手上时,没有什么是安全的,但一些常见做法可能会使攻击者更难窃取数据。
- 把你的主要逻辑(算法)放在服务器端。
- 与服务器和客户端通信;确保服务器和客户端之间的通信通过SSL或HTTPS进行保护;或使用其他技术进行密钥对生成算法(ECC 和 RSA)。确保敏感信息保持端到端加密。
- 使用会话并在特定时间间隔后使其过期。
- 加密资源并按需从服务器获取资源。
- 或者,您可以制作一个混合应用程序,通过
webview
访问系统,保护服务器上的资源+代码
多种方法;很明显,您必须在性能和安全性之间做出牺牲。
APK 签名方案 v2 在 Android 7.0 (Nougat)
PackageManager 类现在支持使用 APK 签名方案 v2 验证应用。APK 签名方案 v2 是一种全文件签名方案,通过检测任何未经授权的 APK 文件更改,显著提高验证速度并加强完整性保障。
为了保持向后兼容性,必须先使用 v1 签名方案(JAR 签名方案)对 APK 进行签名,然后再使用 v2 签名方案进行签名。使用 v2 签名方案时,如果在使用 v2 方案签名后使用其他证书对 APK 进行签名,则验证将失败。
APK 签名方案 v2 支持稍后将在 N 开发者预览版中提供。
http://developer.android.com/preview/api-overview.html#apk_signature_v2
评论
没有办法完全避免对APK文件进行逆向工程。若要保护应用程序资产和资源,可以使用加密。
- 加密将使它更难在不解密的情况下使用。选择一些强大的加密算法会使破解变得更加困难。
- 在主逻辑中添加一些欺骗代码,使其更难破解。
- 如果你能用任何本地语言编写你的批判性逻辑,那肯定会使反编译变得更加困难。
- 使用任何第三方安全框架,如 Quixxi
评论
如果您的应用程序如此敏感,那么您应该考虑服务器端的支付处理部分。尝试更改您的付款处理算法。仅使用 Android 应用程序来收集和显示用户信息(即帐户余额),而不是在 Java 代码中处理付款,而是使用带有加密参数的安全 SSL 协议将此任务发送到您的服务器。创建一个完全加密且安全的 API 来与您的服务器进行通信。
当然,它也可能被黑客入侵,它与源代码保护无关,但将其视为另一个安全层,使黑客更难欺骗您的应用程序。
同意@Muhammad Saqib的观点:https://stackoverflow.com/a/46183706/2496464
@Mumair给出了良好的开始步骤:https://stackoverflow.com/a/35411378/474330
假设您分发到用户设备的所有内容都属于用户,这始终是安全的。简单明了。您可以使用最新的工具和程序来加密您的知识产权,但无法阻止坚定的人“研究”您的系统。即使当前的技术可能使他们难以获得不必要的访问权限,但明天甚至可能有一些简单的方法,甚至只是下一个小时!
因此,等式来了:
在金钱方面,我们总是假设客户是不可信的。
即使是在游戏内经济这样简单的经济中。(尤其是在游戏中!那里有更多“老练”的用户,漏洞在几秒钟内传播!
我们如何保持安全?
我们的大多数(如果不是全部)关键处理系统(当然还有数据库)都位于服务器端。在客户端和服务器之间,存在加密通信、验证等。这就是瘦客户端的理念。
工具:在您的应用程序中使用 ProGuard,可以限制它对您的应用程序进行逆向工程
评论
我可以看到这个问题有很好的答案。除此之外,您还可以使用 Facebook ReDex 来优化代码。ReDex 在 ProGuard 工作的水平上工作。.dex
.class
在 Android 中,源代码和资源的 100% 安全性是不可能的。但是,你可以让逆向工程变得有点困难。您可以在以下链接中找到更多详细信息:
请访问安全保存常量值和面向应用开发者的移动应用安全最佳实践。
我知道一些银行应用程序正在使用 DexGuard,它提供混淆以及类、字符串、资产、资源文件和本机库的加密。
评论