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