我正在开发Android的支付处理应用程序,我想阻止黑客访问APK文件中的任何资源,资产或源代码。
如果有人将.apk扩展名更改为.zip,那么他们可以解压缩它并轻松访问所有应用程序的资源和资产,并使用dex2jar和Java反编译器,他们也可以访问源代码。反向工程Android APK文件非常容易 - 有关更多详细信息,请参阅Stack Overflow问题Reverse engineering from an APK file to a project。
我使用了随Android SDK提供的Proguard工具。当我对使用签名密钥库和Proguard生成的APK文件进行逆向工程时,我得到了混淆代码。
但是,Android组件的名称保持不变,某些代码(如应用程序中使用的键值)保持不变。根据Proguard文档,该工具不能混淆清单文件中提到的组件。
现在我的问题是:
1.如何完全避免Android APK的逆向工程?这可能吗?
AFAIK,完全避免逆向工程没有任何技巧。
@inazaruk也很好地说:无论你对你的代码做什么,潜在的攻击者都能够以任何方式改变它,或者他认为这是可行的。您基本上无法保护您的应用程序不被修改。您放在那里的任何保护都可以被禁用/删除。
2.我如何保护所有应用程序的资源,资产和源代码,以便黑客无法以任何方式破解APK文件?
你可以采取不同的技巧来加强黑客攻击。例如,使用模糊处理(如果是Java代码)。这通常会显着降低逆向工程的速度。
3.有没有办法使黑客攻击更加艰难甚至不可能?我还可以做些什么来保护我的APK文件中的源代码?
正如大家所说,并且你可能知道,没有100%的安全性。但是,谷歌内置的Android起点是ProGuard。如果您可以选择包含共享库,则可以在C ++中包含所需的代码以验证文件大小,集成等。如果您需要在每个构建版本的APK库库中添加外部本机库,那么您可以使用它根据以下建议。
将库放在本机库路径中,默认为项目文件夹中的“libs”。如果你为'armeabi'目标构建了本机代码,那么将它放在libs / armeabi下。如果它是用armeabi-v7a构建的,那么将它放在libs / armeabi-v7a下。
<project>/libs/armeabi/libstuff.so
您可以尝试以下几种方法:
您的客户应该聘请知道自己在做什么的人,谁可以做出正确的决定并指导您。
上面谈到你有能力改变后端的事务处理系统是荒谬的 - 你不应该被允许进行这样的体系结构更改,所以不要指望能够。
我的理由是:
由于您的域名是付款处理,因此可以安全地假设PCI DSS和/或PA DSS(以及潜在的州/联邦法律)对您的业务非常重要 - 为了符合您的要求您必须证明您是安全的。为了不安全,然后找出(通过测试)你不安全,然后修复,重新测试,等等,直到安全性可以在合适的水平上验证=昂贵,缓慢,高风险的成功方式。做正确的事情,提前思考,让有经验的人才投入工作,以安全的方式发展,然后测试,修复(减少)等等(直到安全性可以在合适的水平上验证)=便宜,快速,低风险的成功之道。
作为在支付平台上广泛工作的人,包括一个移动支付应用程序(MyCheck),我会说你需要将这种行为委托给服务器,不应该存储支付处理器的用户名或密码(无论哪个)或者在移动应用程序中硬编码,这是你想要的最后一件事,因为即使你混淆了代码,也可以理解源代码。
此外,您不应该在应用程序上存储信用卡或付款令牌,所有内容应该再次委托给您构建的服务,以后也会允许您,更容易符合PCI标准,并且信用卡公司赢了从你的颈部呼气(就像他们为我们做的那样)。
这里的其他upvoted答案是正确的。我只想提供另一种选择。
对于您认为重要的某些功能,您可以在应用中托管WebView控件。然后,您的Web服务器上将实现该功能。它看起来像是在您的应用程序中运行。
如果我们想要进行逆向工程(几乎)不可能,我们可以将应用程序放在一个高度防篡改的芯片上,该芯片在内部执行所有敏感内容,并与某些协议通信以在主机上实现控制GUI。即使是防篡改芯片也不是100%防裂;他们只是设置了比软件方法更高的标准。当然,这是不方便的:应用程序需要一些小的USB疣,它可以将芯片插入设备中。
这个问题没有揭示出如此嫉妒地想要保护这个应用程序的动机。
如果目的是通过隐藏应用程序可能具有的任何安全缺陷(已知或其他方式)来提高支付方法的安全性,则完全是错误的。如果可行的话,安全敏感位实际上应该是开源的。对于审核您的应用程序的任何安全研究人员,您应该尽可能简单地找到这些位并仔细检查他们的操作,并与您联系。付款应用程序不应包含任何嵌入式证书。也就是说,应该没有服务器应用程序只信任设备,因为它具有来自工厂的固定证书。应仅使用用户的凭据进行支付交易,使用正确设计的端到端身份验证协议,该协议可排除信任应用程序,平台或网络等。
如果目的是防止克隆,缺少防篡改芯片,那么您无法采取任何措施来保护程序不被反向工程和复制,因此有人将兼容的付款方式整合到他们自己的应用程序中,崛起为“未经授权的客户”。有很多方法可以使开发未经授权的客户变得困难。一种方法是根据程序完整状态的快照创建校验和:所有状态变量。 GUI,逻辑,等等。克隆程序不具有完全相同的内部状态。当然,它是一个状态机,具有类似的外部可见状态转换(可以通过输入和输出观察到),但几乎没有相同的内部状态。服务器应用程序可以查询程序:您的详细状态是什么? (即给我一个所有内部状态变量的校验和)。这可以与虚拟客户端代码进行比较,虚拟客户端代码在服务器上并行执行,通过真正的状态转换。第三方克隆必须复制真正程序的所有相关状态更改,以便给出正确的响应,这将妨碍其开发。
我建议你看看Protect Software Applications from Attacks。这是一项商业服务,但是我朋友的公司使用了它,他们很乐意使用它。
Android N中的APK签名方案v2
PackageManager类现在支持使用APK签名方案v2验证应用程序。 APK签名方案v2是一种全文件签名方案,通过检测对APK文件的任何未经授权的更改,显着提高了验证速度并加强了完整性保证。
为了保持向后兼容性,在使用v2签名方案进行签名之前,必须使用v1签名方案(JAR签名方案)对APK进行签名。使用v2签名方案,如果在使用v2方案签名后使用其他证书对APK进行签名,则验证将失败。
APK签名方案v2支持将在N开发者预览版中稍后提供。
http://developer.android.com/preview/api-overview.html#apk_signature_v2
没有办法完全避免APK的逆向工程。要保护应用程序资产和资源,您可以使用加密。
同意@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.
甚至像游戏中的经济一样简单。 (特别是在游戏中!那里有更多“老练”用户,漏洞在几秒钟内传播开来!)
我们如何保持安全?
大多数(如果不是全部)我们的关键处理系统(当然还有数据库)位于服务器端。在客户端和服务器之间,存在加密通信,验证等等。这就是瘦客户端的想法。
AFAIK,您无法保护/ res目录中的文件,而不是现在受到保护。
但是,您可以采取一些步骤来保护您的源代码,或者至少可以采取哪些措施来保护您的源代码。
10000
硬币。而不是直接保存10000
,使用像((currency*2)+1)/13
这样的算法保存它。因此,不是10000
,而是将1538.53846154
保存到SharedPreferences中。但是,上面的例子并不完美,你必须努力想出一个方程式,它不会因为舍入错误而失去货币等。$200
。而不是将原始$200
值发送到服务器,而是发送一系列较小的预定义值,这些值加起来为$200
。例如,在服务器上放置一个文件或表,将单词与值等同。所以,让我们说Charlie
对应$47
,John
对应$3
。因此,不是发送$200
,而是发送Charlie
四次和John
四次。在服务器上,解释它们的含义并将其添加。这可以防止黑客向您的服务器发送任意值,因为他们不知道哪个词对应于什么值。作为安全性的附加度量,您也可以使用类似于第3点的等式,并且每隔n
天数更改关键字。总而言之,没有办法100%保护您的应用程序。你可以让它变得更难,但并非不可能。您的Web服务器可能会受到攻击,黑客可以通过监控多个交易金额以及您为其发送的关键字来找出您的关键字,黑客可以煞费苦心地查看源代码并找出哪些代码是虚拟代码。
你只能反击,但永远不会赢。
基本上这是不可能的。永远不可能。但是,有希望。你可以使用obfuscator来实现它,所以一些常见的攻击很难执行,包括:
a.a
这样的类型)我确定还有其他人,但那是主要的。我在.NET混淆器上为一家名为PreEmptive Solutions的公司工作。他们还有一个适用于Android的Java混淆器以及一个名为DashO的混淆器。
然而,混淆总是带来代价。值得注意的是,性能通常更差,并且通常需要一些额外的时间来释放。但是,如果您的知识产权对您非常重要,那么它通常是值得的。
否则,您唯一的选择就是让您的Android应用程序直接传递到托管应用程序所有真实逻辑的服务器。这有其自身的问题,因为这意味着用户必须连接到Internet才能使用您的应用程序。
此外,不只是Android有这个问题。这是每个应用商店的问题。这只是一个问题,到达包文件有多困难(例如,我不相信它在iPhone上很容易,但它仍然可能)。
它不可能完全避免RE但是通过使它们在内部变得更复杂,你会让攻击者更难以看到app的清晰操作,这可能会减少攻击向量的数量。
如果应用程序处理高度敏感的数据,则会出现各种技术,这些技术会增加代码逆向工程的复杂性。一种技术是使用C / C ++来限制攻击者轻松进行运行时操作。有充足的C和C ++库非常成熟,易于与Android提供JNI集成。攻击者必须首先规避调试限制,以便在低级别攻击应用程序。这进一步增加了攻击的复杂性。 Android应用程序应在应用程序清单中设置android:debuggable =“false”,以防止攻击者或恶意软件轻松操作。
跟踪检查 - 应用程序可以确定调试器或其他调试工具当前是否正在跟踪它。如果被跟踪,应用程序可以执行任意数量的可能的攻击响应操作,例如丢弃加密密钥以保护用户数据,通知服务器管理员或其他此类类型的响应以试图保护自己。这可以通过检查进程状态标志或使用其他技术来确定,例如比较ptrace attach的返回值,检查父进程,进程列表中的黑名单调试器或比较程序的不同位置的时间戳。
优化 - 为了隐藏高级数学计算和其他类型的复杂逻辑,利用编译器优化可以帮助模糊对象代码,使攻击者无法轻易地对其进行反汇编,从而使攻击者更难以理解特定代码。在Android中,通过使用NDK本地编译的库可以更容易地实现这一点。此外,使用LLVM Obfuscator或任何保护程序SDK将提供更好的机器代码混淆。
剥离二进制文件 - 剥离本机二进制文件是增加攻击者所需的时间和技能水平的有效方法,以便查看应用程序的低级功能。通过剥离二进制文件,二进制文件的符号表被剥离,因此攻击者无法轻松调试或反向工程应用程序。您可以参考GNU / Linux系统上使用的技术,如sstriping或使用UPX。
最后,您必须了解混淆和ProGuard等工具。
TPM芯片(可信平台模块)是不是应该为您管理受保护的代码?它们在PC(尤其是Apple)上越来越普遍,它们可能已经存在于今天的智能手机芯片中。不幸的是,还没有OS API可以使用它。希望Android能为这一天增加支持。这也是清理内容DRM(Google正在为WebM工作)的关键。
当你把它放在最终用户手上时没有什么是安全的,但是一些常见的做法可能会使攻击者更难以窃取数据。
webview
访问系统保护服务器上的资源+代码多种方法;很明显,你必须牺牲性能和安全性
如果您的应用程序是敏感的,那么您应该考虑服务器端的付款处理部分。尝试更改您的付款处理算法。仅使用Android应用程序收集和显示用户信息(即帐户余额),而不是在Java代码中处理付款,使用带有加密参数的安全SSL协议将此任务发送到您的服务器。创建完全加密且安全的API以与您的服务器通信。
当然,它也可能被黑客入侵,它与源代码保护无关,但考虑到另一个安全层,使黑客更难欺骗你的应用程序。
如何保护所有应用程序的资源,资源和源代码,以便黑客无法以任何方式破解APK文件?
APK文件受SHA-1算法保护。您可以在APK的META-INF文件夹中看到一些文件。如果您提取任何APK文件并更改其任何内容并再次压缩它,并且当您在Android计算机上运行该新APK文件时,它将无法工作,因为SHA-1哈希将永远不会匹配。
虽然我同意没有100%的解决方案可以保护你的代码,但如果你想尝试一下,HoseDex2Jar的v3现在已经启动了。
工具:在您的应用程序中使用Proguard,它可以限制为逆向工程应用程序
我可以在这个帖子中看到这个好答案。除了你可以使用facebook redex
来优化代码。 Redex适用于.dex
级别,其中proguard工作为.class
级别。
Android中无法实现源代码和资源的100%安全性。但是,对于逆向工程师来说,你可能会有点困难。您可以在以下链接中找到更多详细信息:
访问Saving constant values securely和https://www.agicent.com/blog/mobile-app-security-best-practices/
在计算历史中,任何时候都有可能在向攻击者提供软件的工作副本时阻止软件的逆向工程。而且,最有可能的是,它永远不可能实现。
有了这个,有一个明显的解决方案:不要把你的秘密告诉你的攻击者。虽然您无法保护APK的内容,但您可以保护的是您不分发的任何内容。通常,这是服务器端软件,用于激活,支付,规则执行和其他多汁的代码。您可以通过不将其分发到APK中来保护有价值的资产。相反,设置一个响应来自您的应用程序的请求的服务器,“使用”资产(无论可能意味着什么),然后将结果发送回应用程序。如果此模型不适合您考虑的资产,那么您可能需要重新考虑您的策略。
此外,如果您的主要目标是防止盗版行为:甚至不要打扰。你已经在这个问题上花费了更多的时间和金钱,而不是任何反盗版措施都可能希望能够拯救你。解决这个问题的投资回报率很低,甚至没有意义。
当他们在手机上安装应用程序时,他们可以完全访问它的内存。因此,如果你想阻止它被黑客攻击,你可以尝试使它不能直接通过调试器获取静态内存地址。如果他们有可以写入的地方并且有限制,他们可以执行堆栈缓冲区溢出。因此,当他们写东西时,如果你必须有一个限制,如果他们发送更多的字符而不是限制,如果(输入>限制)然后忽略,那么尝试这样做,所以他们不能把汇编代码放在那里。
应用程序安全性的第一条规则:攻击者获得不受限制的物理或电子访问权限的任何计算机现在属于您的攻击者,无论其实际位置或您为此付出的代价。
应用程序安全性的第二条规则:任何离开攻击者无法攻击的物理边界的软件都属于您的攻击者,无论您花多少时间编写它。
第三条规则:任何留下攻击者无法穿透的物理边界的信息都属于您的攻击者,无论它对您有多大价值。
信息技术安全的基础是基于这三个基本原则;唯一真正安全的计算机是一个锁在保险箱内的计算机,位于Farraday笼内,钢笼内。有些计算机的大部分服务时间都处于这种状态;每年一次(或更少),他们为受信任的根证书颁发机构生成私钥(在一群见证人面前,摄像头记录他们所在房间的每一寸)。
现在,大多数计算机都不在这些类型的环境中使用;他们在公开场合,通过无线电频道连接到互联网。简而言之,它们和软件一样容易受到攻击。因此,他们不值得信任。计算机及其软件必须知道或做某些事情才能发挥作用,但必须注意确保他们永远不会知道或做得不够造成损害(至少不会造成超出单一机器范围的永久性损坏) )。
你已经知道了这一切;这就是为什么你要保护你的应用程序的代码。但是,这是第一个问题;混淆工具可以使代码变得混乱,人类试图挖掘,但程序仍然必须运行;这意味着应用程序的实际逻辑流程及其使用的数据不受混淆的影响。如果有一点韧性,攻击者可以简单地对代码进行非混淆,并且在某些情况下甚至不需要他所看到的东西除了他正在寻找的东西之外什么也不是。
相反,您应该尝试确保攻击者无法对您的代码执行任何操作,无论他获得清晰的副本是多么容易。这意味着,没有硬编码的秘密,因为一旦代码离开您开发它的建筑物,这些秘密就不是秘密。
您已硬编码的这些键值应完全从应用程序的源代码中删除。相反,他们应该在三个地方之一;设备上的易失性内存,攻击者获取离线副本更难(但仍然不是不可能);永久地在服务器群集上,用铁拳控制访问;或者在与您的设备或服务器无关的第二个数据存储中,例如物理卡或用户的存储器(意味着它最终将存在于易失性存储器中,但它不必长时间存在)。
考虑以下方案。用户将应用程序的凭据从内存输入设备。不幸的是,您必须相信用户的设备尚未受到键盘记录器或特洛伊木马的攻击;在这方面你能做的最好的事情是通过记住关于用户使用的设备(MAC / IP,IMEI等)的难以辨认的识别信息,并通过以下方式提供至少一个附加信道来实现多因素安全性。可以验证对不熟悉设备的登录尝试。
一旦输入,凭证就会被客户端软件(使用安全散列)进行模糊处理,并丢弃纯文本凭证;他们达到了目的。模糊的凭证通过安全通道发送到经过证书认证的服务器,再次对其进行哈希处理,以生成用于验证登录有效性的数据。通过这种方式,客户端永远不会知道实际与数据库值进行比较的内容,应用服务器永远不会知道它收到的验证背后的明文凭据,数据服务器永远不会知道它为验证存储的数据是如何产生的,而且即使安全渠道受到损害,中间人也只会看到胡言乱语。
一旦验证,服务器就通过信道发送回令牌。令牌仅在安全会话中有用,由随机噪声或会话标识符的加密(因此可验证)副本组成,并且客户端应用程序必须在同一通道上将此令牌作为任何请求的一部分发送到服务器做某事。客户端应用程序会多次执行此操作,因为它无法执行任何涉及金钱,敏感数据或其他任何可能造成损害的事情;它必须要求服务器执行此任务。客户端应用程序永远不会将任何敏感信息写入设备本身的持久性内存,至少不能以纯文本形式写入;客户端可以通过安全通道向服务器请求对称密钥来加密服务器将记住的任何本地数据;在以后的会话中,客户端可以向服务器请求相同的密钥来解密数据以便在易失性存储器中使用。这些数据也不是唯一的副本;客户端存储的任何内容也应以某种形式传输到服务器。
显然,这使您的应用程序严重依赖于Internet访问;如果没有与服务器正确连接和认证,客户端设备就无法执行任何基本功能。与Facebook没什么不同,真的。
现在,攻击者想要的计算机就是你的服务器,因为它而不是客户端应用程序/设备是可以让他赚钱或让其他人为他的享受而痛苦的东西。没关系;你可以花更多的钱购买服务器,而不是试图保护所有客户端。服务器可以支持所有类型的防火墙和其他电子安全设备,此外还可以在钢铁,混凝土,钥匙卡/插针访问和24小时视频监控背后进行物理保护。您的攻击者确实需要非常复杂才能直接获得对服务器的任何访问权限,您应该(应该)立即了解它。
攻击者可以做的最好的事情就是窃取用户的电话和凭据,并使用客户端的有限权限登录服务器。如果发生这种情况,就像丢失信用卡一样,应该指示合法用户拨打800号码(最好是容易记住,而不是在他们的钱包,钱包或公文包中随身携带的卡片背面)他们可以访问任何直接连接到客户服务的手机,与移动设备一起被盗。他们声称他们的手机被盗,提供一些基本的唯一标识符,并且帐户被锁定,攻击者可能已经处理的任何交易都被回滚,攻击者又回到原点。
1.如何完全避免Android APK的逆向工程?这可能吗?
这是不可能的
2.我如何保护所有应用程序的资源,资产和源代码,以便黑客无法以任何方式破解APK文件?
当某人将.apk扩展名更改为.zip时,解压后,有人可以轻松获取所有资源(Manifest.xml除外),但使用APKtool,也可以获取清单文件的真实内容。再一次,没有。
3.有没有办法使黑客攻击更加艰难甚至不可能?我还可以做些什么来保护我的APK文件中的源代码?
同样,不,但你可以防止达到一定程度,即
即使使用Smali
,人们也可以使用您的代码。总而言之,这不可能。
不可能100%避免Android APK的逆向工程,但您可以使用这些方法来避免提取更多数据,例如源代码,资源形成您的APK和资源:
.so
文件中开发人员可以采取以下措施防止APK以某种方式被盗,
ProGuard
这样的工具来混淆他们的代码,但到目前为止,完全阻止某人反编译应用程序是相当困难的。Dex2Jar
,该APK会混淆和禁用Dex2Jar
并保护代码免受反编译。它可以以某种方式阻止黑客将APK反编译成可读的Java代码。完全没有,你无法完全保护你的代码免受潜在的黑客攻击。不知何故,你可能会让它们反编译你的代码变得困难而且有点令人沮丧。最有效的方法之一是用本机代码(C / C ++)编写并将其存储为编译库。
1.如何完全避免Android APK的逆向工程?这可能吗?
不可能
2.我如何保护所有应用程序的资源,资产和源代码,以便黑客无法以任何方式破解APK文件?
不可能
3.有没有办法使黑客攻击更加艰难甚至不可能?我还可以做些什么来保护我的APK文件中的源代码?
更加艰难 - 可能,但事实上,对于普通用户而言,这将更加艰难,他们只是在谷歌搜索黑客指南。如果有人真的想破解你的应用程序 - 它迟早会被黑客入侵。
1.如何完全避免Android APK的逆向工程?这可能吗?
那是不可能的
2.我如何保护所有应用程序的资源,资产和源代码,以便黑客无法以任何方式破解APK文件?
开发人员可以采取诸如使用ProGuard等工具来混淆代码的步骤,但到目前为止,完全阻止某人反编译应用程序是非常困难的。
它是一个非常好的工具,可以增加“反转”代码的难度,同时缩小代码的占用空间。
集成的ProGuard支持:ProGuard现在与SDK工具一起打包。开发人员现在可以将其代码混淆为发布版本的集成部分。
3.有没有办法使黑客攻击更加艰难甚至不可能?我还可以做些什么来保护我的APK文件中的源代码?
在研究时,我开始了解HoseDex2Jar。此工具将保护您的代码免受反编译,但似乎无法完全保护您的代码。
一些有用的链接,你可以参考它们。