应用程序安全的第一条规则:攻击者获得不受限制的物理或电子访问权限的任何机器现在都属于您的攻击者,无论它实际在哪里或您为此支付了什么费用。
应用程序安全的第二条规则:任何离开攻击者无法渗透的物理边界的软件现在都属于您的攻击者,无论您花了多少时间编写它。
第三条规则:任何离开攻击者无法穿透的物理边界的信息现在都属于你的攻击者,无论它对你有多有价值。
信息技术安全的基础基于这三个基本原则;唯一真正安全的计算机是锁在保险箱里、法拉第笼子里、钢笼子里的那台。有些计算机的大部分使用寿命都处于这种状态。每年(或更少)一次,他们为受信任的根证书颁发机构生成私钥(在众多目击者面前,用摄像头记录他们所在房间的每一寸)。
现在,大多数计算机都不是在这些类型的环境下使用的;它们实际上是在户外,通过无线电频道连接到互联网。简而言之,它们很容易受到攻击,就像它们的软件一样。因此,他们不值得信任。计算机及其软件必须知道或做某些事情才能发挥作用,但必须注意确保它们永远不会知道或做的事情足以造成损害(至少不会造成超出单台机器范围的永久性损害) )。
你已经知道了这一切;这就是您试图保护应用程序代码的原因。但是,这是第一个问题;混淆工具可以使代码变得一团糟,人类试图挖掘,但程序仍然必须运行;这意味着应用程序的实际逻辑流程及其使用的数据不受混淆的影响。只要有一点韧性,攻击者就可以简单地对代码进行去混淆处理,在某些情况下,这甚至是不必要的,因为他正在查看的内容只能是他正在寻找的内容。
相反,您应该努力确保攻击者无法对您的代码做任何事情,无论他多么容易获得它的清晰副本。这意味着,没有硬编码的秘密,因为一旦代码离开您开发它的建筑物,这些秘密就不是秘密了。
您硬编码的这些键值应从应用程序的源代码中完全删除。相反,它们应该位于三个位置之一;设备上的易失性内存,攻击者更难(但仍然不是不可能)获得离线副本;永久在服务器集群上,您可以用铁腕控制对它的访问;或在与您的设备或服务器无关的第二个数据存储中,例如物理卡或用户的内存中(这意味着它最终将在易失性内存中,但不必很长时间)。
考虑以下方案。用户将他们的应用程序凭据从内存输入到设备中。不幸的是,您必须相信用户的设备尚未被键盘记录器或木马入侵;在这方面,您可以做的最好的事情是实施多因素安全性,通过记住有关用户使用的设备(MAC/IP、IMEI 等)的难以伪造的识别信息,并通过以下方式提供至少一个额外的通道可以验证在不熟悉的设备上的登录尝试。
凭据一旦输入,就会被客户端软件混淆(使用安全散列),并丢弃纯文本凭据;他们已经达到了他们的目的。混淆后的凭证通过安全通道发送到经过证书验证的服务器,服务器再次对其进行哈希处理以生成用于验证登录有效性的数据。这样,客户端永远不知道实际与数据库值相比的是什么,应用服务器永远不知道它接收到的用于验证的明文凭据,数据服务器永远不知道它存储的用于验证的数据是如何产生的,并且一个人在即使安全通道遭到破坏,中间人也只会看到胡言乱语。
一旦经过验证,服务器就会通过通道发回一个令牌。令牌仅在安全会话中有用,由随机噪声或会话标识符的加密(因此可验证)副本组成,客户端应用程序必须在同一通道上将此令牌作为任何请求的一部分发送到服务器做某事。客户端应用程序会多次这样做,因为它不能做任何涉及金钱、敏感数据或任何其他可能对其自身造成破坏的事情;它必须改为要求服务器执行此任务。客户端应用程序永远不会将任何敏感信息写入设备本身的持久内存中,至少不会以纯文本形式;客户端可以通过安全通道向服务器请求对称密钥来加密服务器将记住的任何本地数据;在以后的会话中,客户端可以向服务器请求相同的密钥来解密数据以在易失性存储器中使用。该数据也不会是唯一的副本;客户端存储的任何内容也应该以某种形式传输到服务器。
显然,这使您的应用程序严重依赖 Internet 访问;如果没有与服务器的正确连接和验证,客户端设备将无法执行其任何基本功能。真的,和 Facebook 没有什么不同。
现在,攻击者想要的计算机是您的服务器,因为它而不是客户端应用程序/设备可以让他赚钱或让其他人为他的享受而痛苦。没关系; 与尝试保护所有客户端相比,花费金钱和精力来保护服务器会获得更多的收益。该服务器可以位于各种防火墙和其他电子安全系统之后,此外还可以在钢筋、混凝土、钥匙卡/密码访问和 24 小时视频监控之后进行物理保护。您的攻击者确实需要非常复杂才能直接获得对服务器的任何类型的访问权限,并且您将(应该)立即知道它。
攻击者能做的最好的事情就是窃取用户的电话和凭据,并以客户端的有限权限登录服务器。如果发生这种情况,就像丢失信用卡一样,应该指示合法用户拨打 800 号码(最好容易记住,而不是在他们随身携带的钱包、钱包或公文包中的卡片背面与移动设备一起被盗)从他们可以访问的任何电话直接连接到您的客户服务。他们声称他们的手机被盗,提供了一些基本的唯一标识符,并且帐户被锁定,攻击者可能能够处理的任何交易都被回滚,攻击者又回到了原点。