查看原文
其他

从加密到验证,全方位保障您应用的通讯安全

Android Android 开发者 2021-08-05

在一个完美的世界上,没有人需要用到密码。每个人都高度自律,心无邪念;每件快递都能不经拦截准确送达收件人;而每个寄件者都是值得信赖的。但是我们并不在这样完美的世界中生存。过去的数十年间,密码学已经发展到不仅可以通过加密来保障机密性,还可以确保消息的完整性、身份验证,以及不可否认性——所有的一切都是为了保证消息私密、真实和可靠。


假如您的系统已经实现了强有效的密码策略,这可能会使您认为不再需要通过生物特征来验证就是用户本人。为了理解为什么验明用户正身在密码学中如此重要,让我们依次对照来看密码学中几种方法的成功和不足之处。由此,作为诸如银行系统或医疗系统等高端服务的提供者,可以了解为什么您可能需要在密码策略的基础上进一步实现基于生物特征的身份验证功能。



仅凭加密无法防御某些特定类型的攻击



您可以把加密比作一个函数,比如 E,这个函数接收两个参数,消息 m 和密钥 k,并由此生成密文 c。生活中人们常常把这个密文当作加密,但事实上加密指的是能够生成攻击者无法读取的加扰信息的算法,而最终的加扰信息就是密文。

c = E(m,k)

只要密钥 k 足够长,当您仅知道 mc 部分内容时,几乎不可能得出密钥 k。但是,攻击者无需解密消息即可对其进行篡改,攻击者也许可以编辑密文、删除密文,或者以重放的方式重新发送一条包含密文的消息。
 
并不是所有的攻击者都想要盗窃您的数据;他们可能只想给您带来不便。试想有一个攻击者,他只是重放了您向电脑城付款 $2,000 购买笔记本的加密交易。假设他是与该电脑城没有任何联系的攻击者,所以他什么也没有偷走。您固然可以通过一些申诉手段向店家要回退款,但既蒙受了时间的损失又没了好心情。更糟糕的是,某些精于此道的攻击者也许会将电脑城的银行账户替换为其他银行账户——这一切完全不需要解密您传输的密文。

当然,刚才的这些都只是接触了其中的皮毛。针对纯加密方案的攻击有许多更知名的案例。即使您的加密算法充分防范了已知的攻击手段,但仍可能会有不足。简单说来,您没办法永远保证消息的私密性。甚至是在最佳密码学策略的加持下,当下技术的发展速度只能让您的消息在 30 年内保持私密,或许运气好的话,能有 50 年。因此,仅凭加密是无法与破坏消息完整性的攻击者相抗衡的。您还需要用上身份验证手段,也就是下个小节要探讨的问题。



通过消息身份认证保证消息不被篡改



在一些敏感场合中,欺骗性质的消息误传会造成破坏性影响。这个重要的事实启发安全工程师们创造了消息认证码 (Message Authentication Code,简称 MAC 或 HMAC)。如果发信人在发送消息的同时还传输了 MAC,那么攻击者就无法再修改内容并假装这就是原始消息。同时攻击者也无法重放已经发送过的消息。攻击者能做到的最多就是删除发送的消息造成通讯失败。
 
MAC 是什么?MAC a 与通过消息和密钥计算得到的密文相似。本质上,发信人将消息 m 和密钥 k 传入函数 h 计算就能生成 MAC 了。随后,发信人同时将消息和 MAC 发送给收信人。

m,a = h(m,k)

MAC 与单条消息并不是唯一对应的,这是由于鸽笼原理导致的,大致意思是如果您的鸽子数量比鸽笼要多,那么某些鸽笼中就不止一只鸽子了。MAC 的长度是预先就决定了的,因此消息的数量会比对应 MAC 的数量要多。但是由于搜索域太大,攻击者想要在不知道密钥的情况下很难猜出修改后的消息对应的 MAC。因此,MAC 能够有效防止消息被修改的原因是只有发件人和目标收件人知道密钥。如果攻击者想要修改发送的消息,那么他必须替换 MAC 以匹配更改。但是在不知道密钥的情况下这几乎是不可能的。由于连续两次计算 m,a = h(m,k) 会生成两个不同的 MAC,消息重放攻击也会随之失效。这是因为在实践中通常还有第三个严格增加的参数 t: 因此公式写作 m,a = h(m,k,t)。由此,MAC 函数能帮助合法的收件人轻松验证是否遭遇了消息重放攻击。
 
MAC 机制本质上使得攻击者必须破解密钥。由于 MAC 的存在,模仿原始消息不再可行。消息完整性得到根本保障。虽然 MAC 机制非常实用,但在机密性方面它仍然有局限,这也是后面章节要说明的问题。

 


已签名但未封装



值得注意的是,MAC 只是对消息进行了签名而没有将其封装——也就是没有机密性。攻击者仍然可以读到消息的内容;只不过他们无法轻松篡改内容。但是同时进行签名和封装并不难。我们不再使用 m,a = h(m,kₐ),取而代之的是通过代数替换得到 c,a = h(c,kₐ) ,其中 c 是由 c= E(m,k𝒸) 计算得出的。
 
好的密码算法就像是好房子。它们可以在狂风暴雨中屹立 30 年以上,而不是仅存在一天就坍塌。特别是对于密码学家来说,这意味着他们需要预见在未来的 10 年或是 30 年后攻击者会以当下尚未发明的技术来破解加密算法,而不是仅考虑攻击是否会在明天或下个月发生。因此,MAC 并不能使加密牢不可破。它只是增加了攻击者的破解难度。30 年后的攻击者可能会用生日攻击中途相遇攻击来猜测经过篡改的消息的 MAC 值,从而使收信人接到假冒的消息。


  • 生日攻击
    https://en.wikipedia.org/wiki/Birthday_attack#:~:text=A%20birthday%20attack%20is%20a,between%20two%20or%20more%20parties.
  • 中途相遇攻击
    https://en.wikipedia.org/wiki/Meet-in-the-middle_attack



非对称加密让扩展更从容



目前为止,我们谈到了密码学家如何搭配加密和 MAC 来生成签名且封装的消息。我们也谈到了攻击者所能做的最多就是删除这些消息;否则消息会成功、私密、完整地送达收信人。听起来这就是我们所需要的全部了,其实还有更多。在我们开始讨论 "更多" 之前,不妨先聊聊可扩展性。
 
目前为止我们讨论的大多数技术被统称为对称密码学。简言之,它们要求发信人和收信人都是用完全相同的密钥来加密或者解密消息,以及创建或校验 MAC。这种方法的问题在于,如果整个群组有 10 名成员,那么每名成员都需要分享和存储 9 个不同的密钥,这样才能够在任意两名成员之间互发加密信息。这样一来,整个群组就有 45 个 key 存在。如果有 20 个人,就有 190 个密钥;一般地, n 个人就有 (n-1)n/2 个密钥。假想一下,如果对联系人列表里的每个人,您都需要使用一个独立手机号码与其联系会怎样?这样一来,您不能将一个号码发给所有的联系人,而每次结交新朋友,您都需要购买一个新的手机号码!这就是对称加密的问题所在。难以扩展。不过幸好还有非对称加密可用。

非对称密码学使用数论中的观点 (尤其是有限域理论单射函数) 来实现其技术优雅。本质上是每个人都创建一个公钥和一个私钥。任何想要和您交流的人可以使用您的公钥来加密信息,但只有您的私钥可以将其解密。

  • 有限域理论
    https://mathworld.wolfram.com/FiniteField.html
  • 单射函数
    https://mathworld.wolfram.com/One-WayFunction.html

这里意在讨论非对称加密,而不是深入探讨数论。要支持不可否认性,您必须要使用到非对称加密,这是我们接着要讨论的下一个密码学属性。

 


必要的不可否认性



不可否认性是 "不可食言" 的专业说法。电子商务革命把这个简单的公平交易原则带到密码学领域的前沿和中心。
 
在使用对称密钥的情况下,收到消息的人 (比如 Bob) 没办法向法官证明发信人 (比如 Alice) 是真正发消息的那个人。这是因为 Alice 和 Bob 用相同的密钥来通讯。或许 Alice 真的发送了原始消息,但 Bob 篡改了它,抑或 Alice 在撒谎。裁判没办法判断到底是哪一种情况。
 
然而在使用非对称密钥时,只有持私钥的那个人才可以对消息签名。全世界任何人都可以读到消息的内容,毕竟公钥是公开的。因此会出现这样的情况: 当 Alice 需要从 Bob 那边买东西时,她会用 Bob 的公钥来加密交易,并使用她自己的私钥来签名。然后当 Bob 收到交易信息后,可以用 Alice 的公钥来确定是不是真的用 Alice 的私钥签的名,随后用他自己的私钥来解密消息。由此可见,签名就被用来提供不可否认性了。MAC 和签名本质上是一样的,不过前者是对称加密的概念,而后者属于非对称加密。

 


简单回顾



现在我们来回顾一下。密码学被应用于加密和认证消息,并且提供不可否认性。当使用了正确的技术,消息的真实性和加密性两方面都难以被破解——它们都依赖较为复杂的数学手段,比如整数分解、离散对数和椭圆曲线算法,这些方法随后被应用于有限域问题中。需要指出的是,通过数学分析来获得加密密钥可能会很困难,但是仍有其他方法可以攻入安全系统,比如社会工程学,也就是人可能被诱导泄密。此外,我们没有聊到密钥生成和认证的过程,因为我们已经说得很明确了: 作为一门工程学科,密码学会根据时代的发展而不断演进,并试图保持超前攻击者。
 
与加密和身份认证不同,不可否认性会更难对付一点,因为用户身份的验证可以为攻击者再添一层难度。

 


用户在场的重要性



到目前我们已经了解到密码学就是在研究安全等级: 对于一个攻击者来说,扰乱通讯的代价 (时间、金钱和体力) 有多么高。尽管如此,仍然存在一个主要问题: 仅凭消息发自我所持有的设备且由我的私钥签名,并不能说明是我本人发送的消息。病毒或是未经授权的用户也有可能发送了该消息。由于这些以及类似的原因,尽管数字签名已经被纳入国际法律体系中,比如 ESIGN,许多跨国商贸机构仍然没有信任它,因为在无法证明用户在场的情况下很难保证不可否认性,而举证责任由商家承担。

  • ESIGN
    https://en.wikipedia.org/wiki/Electronic_Signatures_in_Global_and_National_Commerce_Act 

为了增强商家对不可否认性的信心,业界引入了双重要素验证 (2FA)。因为网络罪犯常常会破解那些仅受用户名和密码保护的在线账号,2FA 引出了让自称是合法用户的代理提供多一种信息的概念。这里所说的多一种信息,通常指的是以下三类中的一种: 某件您知道的事、某样您拥有的事物,或是您是谁。2FA 的目标是要给商家信心去相信,用户本人的确在进行交易。两种常见的 2FA 形式是电子钥匙链和通常由短信发送的验证码。使用电子钥匙链或相似的硬件令牌都有容易丢失或被盗的问题。而当遗失或被窃的设备就是接收短信或者推送通知的设备时,用短信验证码作 2FA 也就毫无抵御能力了。因此,如今 2FA 最先进的形式就只剩您身体的一部分。生物特征身份验证就是这种增强 2FA 的例子。


  • 双重要素验证 (2FA)

    https://en.wikipedia.org/wiki/Multi-factor_authentication


在您的安全策略实现中用生物识别特征验证是否为用户本人,可以让您的应用更安全,并且不可否认性成为了您的商业模式中的一个可靠特性。对于医疗保健或是酒店服务业应用来说,这能够确保更真实的用户登记或是取消预约情况。对于电子商务和银行应用,这使得您的客户服务团队花费更少的时间来处理顾客的小孩意外产生的购买行为和退款,从而有更多的时间以更多令人满意的方式使顾客开心。
 
使生物特征认证在您的安全系统中成为阻拦攻击者的额外障碍的根本原因在于: 虽然生物识别和密码学手段是相互完全独立的措施,但它们都使得攻击者难以攻破。因此,两者结合就可以让攻击者更难以得逞。
 
举个例子,在 Android 当中,生物特征识别像是一条单行道。用户的生物特征信息永远不会离开设备,而且绝不会与应用共享。当用户决定把自己的生物特征信息录入 Android 设备时,他们必须要通过系统的设置应用。倘若用户要使用指纹或是人脸识别,那么他们需要把手指放在传感器上,传感器会直接把指纹图像发送到 Android 设备的受限区域内,这个区域被称为可信执行区域 (TEE)。随后,当您的应用需要通过生物特征验证用户本人在操作时,Android 框架和运行于 TEE 中的生物识别系统会替您的应用处理整个 "用户是否在场" 的验证过程。由于 Android 框架让冒充设备主人的生物特征非常困难,您可以给这个用户本人验证充分的信心。
 
您可以通过阅读我们的文章《结合使用 BiometricPrompt 和 CryptoObject》,更深入了解在 Android 系统上生物特征验证是怎样用不可否认性来增强您应用的安全的。
 
  • 结合使用 BiometricPrompt 和 CryptoObject
    https://medium.com/androiddevelopers/using-biometricprompt-with-cryptoobject-how-and-why-aace500ccdb7


总结



您在本篇文章中了解到了:
  • 为什么良好的密码策略实现需要强调私密性、真实性和不可否认性。

  • 为什么只使用加密不足以保护消息免受攻击。

  • 为什么 MAC 或 HMAC 能够有效避免消息被篡改。

  • 为什么非对称加密比对称加密更容易扩大规模。

  • 为什么现实生活中,不采用生物特征验证就难以实现不可否认性。

  • 为什么生物特征验证可以通过用户存在性验证来增强加密实现。

  • 在哪里可以了解到如何在您的应用中实现生物特征验证。


我们还撰写了许多文章,它们涉及工程最佳实践、设计指南以及将生物特征验证集成到您应用中的技巧:
  • 如果您想要了解怎样在您的应用中实现生物特征验证,请阅读系列文章:

  • 如果您的应用中有使用了 FingerprintManager 的旧逻辑,我们建议您用 BiometricPrompt 取代它。

    • 全面了解 BiometricPrompt,请阅读: 在所有 Android 设备中使用统一的生物识别身份验证 API

      https://android-developers.googleblog.com/2019/10/one-biometric-api-over-all-android.html

    • 了解怎样完成迁移工作,请阅读: 从 FingerprintManager 迁移到 BiometricPrompt

      https://medium.com/androiddevelopers/migrating-from-fingerprintmanager-to-biometricprompt-4bc5f570dccd


祝您编程愉快!


 点击屏末 | 阅读原文 | 即刻了解密码和生物特征如何让您的应用更私密安全


推荐阅读

如页面未加载,请刷新重试


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存