Airbnb技术大牛桑立锋解析:数据加密都有哪些套路?

简介:
  说到桑同学,那比我牛出不止一个数量级了。俄亥俄州立大学毕业的PhD,曾在Yahoo!、LinkedIn等多家公司担任技术骨干。在过去三四年间获各种数据加密相关的专利达五项之多。

除了技术扎实,桑同学平时也是极好相处,又特别愿意帮助别人。在我过去和他不多的几次合作中,也不时又机会请教一二。虽然对于数据加密仍然是个门外汉,但是桑同学解释问题总能听得懂。因此在我的再三请求下,有了这篇科普性的文章。

虽然我们都就职于Airbnb,但是这篇文章和 Airbnb 现在使用的技术没有直接关联。下面是正文。

数据加密是一个古老的问题,但又是一个无法做到完美的问题,尤其在一个复杂的大型系统中需要考虑方方面面的问题,包括 security, availability, usability, consistentcy, performance,extensibility 等等。除了那些完全不做的,大部分公司都会根据自身的需求、环境、资源以及工程师的能力等,设计和开发适合公司实际情况的解决方案。有做得好的,也有坦诚做得不好的,还有自己认为做得好的但其实经不起真正考验的。

就算在同一个公司,很多也会有不同的解决方案并存。有些是因为历史原因,比方说早期用方案A,后来开发了更牛逼的方案B,但没有把A完全干掉;或者扩张原因,比方说兼并了一个用不同方案的别家公司;又或者是政治原因,不同部门谁都不屌谁,各自用自认为合适的方案。无论公司选择什么方案,因为话题的敏感性(法律原因,或者圈内的潜规则,或者仅仅是不想当出头鸟而被黑客们盯上),绝大部分都不会公开数据加密的细节。同样原因,这篇文章也不会涉及笔者公司怎么做数据加密的具体细节。想到哪儿写到哪儿吧。

一、为什么要做数据加密?

先说为什么要做数据加密。越来越多的数据泄露事件,比方说 Yahoo 2013年被盗超过10亿用户信息,Yahoo 2014年又被盗超过5亿用户信息,LinkedIn 被盗一亿多用户密码,Ashley Madison 被盗三千多万用户数据以及大量支付信息,Target 被盗近七千万用户数据和银行账号,Adobe 被盗三千八百万用户数据等等,以及由此导致的大量法律纠纷和巨额赔偿,还有很多很多大大小小没有被公布的安全事件,都说明了数据加密和保护的重要性。

说到这些安全事件中用户密码的保护,插个题外话。笔者曾经跟很多工程师(包括很多应用领域专家)聊天的时候,都会被问到,为什么笔者认为仅仅 Hash 用户密码是不够的。很多人(包括网上的很多文章)都误认为用户密码只要 Hash了,就安全了,其实不然。不说 weak Hash 函数诸如 RC4、MD5,就算用 Bcrypt、KDF等运算复杂的Hash函数,虽然能防 Rainbow Table Attack,但对 Dictionary Attack 却是无效的。当然这不是 Hash 函数本身的错,而是很多人会选一个容易记的密码,而这类密码往往 entropy 不够,很容易被解密。对用户密码而言,笔者一直建议不仅需要Hash,还要加密(比方说用 keyed hash function,or MAC)。

还有很多公司要做加密不仅仅是因为保护用户隐私,更是法律法规的要求,不得不做。有些涉及特殊数据,如信用卡号码,那就要做 PCI (The Payment Card Industry Data Security Standard );如用户健康信息,那就要做 HIPAA (The Health Insurance Portability and Accountability Act)等等。

在笔者看来,任何一个收集以及存储客户数据的公司,就算是初创公司,都应该认真对待这个问题。在圈内我们常说,不是系统会不会黑,数据会不会被盗,而是何时被黑被盗的问题。也许有人会说,就算偷了,盗了,那又如何?这种事可大可小,笔者私下就知道有公司被黑后,被迫关门了的。所以安全领域内的及时投资,对公司长期来讲都是非常有益的。对重要数据(包括系统密码,用户信息等)进行有效保护,数据被黑被盗的门槛就高了;就算有一天系统被黑了,数据被盗了,也能把损失降到最小。

二、怎么做数据加密?

你说数据加密这么重要,怎么做呢?如果把加密这个问题抽象出来,其实就是要计算一个加密函数:

encrypt(data, key)

(当然还有一个函数就是解密,跟加密类似道理,暂且不论)。看上去似乎是一个非常简单的问题,但要把它做好非常不容易。尤其是在一个系统复杂的公司,要考虑的问题很多很多。比方说,密码界有很多算法,应该用什么加密算法,对称的还是非对称的?具体选哪个,AES,DES,RSA,ECC等等,各有什么特点?题外话,笔者在曾经工作过的公司见过很多有趣的例子,比方说有些早期开发人员用 XOR 来加密,或者做点简单的迭代替换,或者自创所谓的加密算法(有点掩耳盗铃的感觉)等等,这些最后都变成 technical debt,需要花很大力气去清理。

每个算法也有不同的变种和模式,各有什么特点,性能如何?如果某个算法被宣布不安全了,如何快速迭代?这个 key 怎么来?多长才是安全的?怎么启动?怎么保存?怎么传播?怎么控制访问权限?怎么知道谁访问了什么?怎么来监控?怎么来预警?怎么来系统性的更新这些 key?key 能不能丢,丢了怎么办?不同的应用可能是用不同的语言写的,怎么兼容?怎么支持大流量等等,等等。还有更加不近人情的要求,比方说如何保证被加密的数据能够 preserve 原始数据的顺序,支持搜索,但又不牺牲安全性等(这方面 MIT 有学者在研究,有兴趣的朋友可以看看他们的论文)。

一个好的加密设计方案,不仅仅方案本身要满足安全上严格的要求,解决上面提到的很多问题,还需要实用,容易扩展和维护。在数据加密变得越来越重要,系统越来越复杂的年代,如果资源允许,应该把加密服务独立出来,然后提供高性能,统一,简单又容易理解的接口来进行数据加密,让应用开发人员很方便的使用,这样他们只需要专注他/她所擅长的领域,而不需要去思考怎么解决安全问题,因为术业有专攻。好的加密方案应该把数据和秘钥的存储分开,并且把存储和运算分开,尤其在 SOA 架构下, 这可能跟很多传统的数据加密方法(比方说直接实用某个语言的内置库加密解密)非常不一样。很多解决方案往往密钥和被加密的数据同时存在一个服务中,结果就是如果那个服务被黑了,那就整个被黑了。下面就捡几个要点简略讲讲。

(1)为什么要把运算和存储的分离?很多需要被加密的数据,往往和具体商业逻辑数据一起,属于不同的服务,比方说支付信息属于支付服务,护照号码属于用户服务等。把运算和存储分离可以带来很多好处,比方说:

  • 加密服务变得简单和高效。因为不需要存储那些被加密的数据,加密服务系统不会很复杂,也不需要负责存储系统所带来的维护,扩展等诸多问题;

  • 加密服务的安全性能提高很多。因为运算和存储的分离,如果仅仅是被加密的数据泄露(比方说数据库被盗),那些数据就没法被解密,因为黑客没法从外部访问加密服务。如果仅仅是客户服务被黑,想要盗取大量数据并且通过加密服务来解密而不被发现也很难。如果仅仅是加密服务服务被黑,因为加密服务本身并不拥有数据,被泄露的数据也不会很多。只有当加密服务和客户服务同时被黑,才会泄露大量数据,而同时能够侵入加密服务和客户服务的难度要高很多很多;

  • 灵动性。因为数据属于客户服务,不同的客户可以对数据进行不同的处理,比方说不同的有效性规则,数据交易完整性等等。

(2)其次是 granular control。假设支付服务要求加密/解密信用卡号码,用户服务要求加密/解密护照号码,如何能保证用户服务不能加密/解密信用卡号码。这就需要解决两个基本问题:客户认证(authentication)和权限控制(authorization)。怎么做客户认证(authentication)?客户认证要知道每一个请求是谁发出的。因为只有知道客户是谁才可以进行权限检查。常用的有基于客户证书的(如 client certificate over TLS),基于 OAuth(开放授权)的,或者各种各样定制的方案,如基于 Curve25519 等等。笔者一般遵循两个原则:

  • 是不是业界公认的。如果不是,最好避免。业界公认的解决方案往往经过过严格的检验, 评价,批评,经得起考验;

  • 有没有广泛的类库支持,以及多语言的支持。如果有,可以节省大量的开发以及维护的时间和精力。

(3)数据监控和预警。为了审计以及安全的需求,一般要对加密服务做很多的数据监控,预警的工作。这样可以知道谁在访问这些数据,何时访问的,怎么访问的,访问的模式是怎么样的。监控系统还需要侦测异常的流量变化,进行流量控制以及快速的反攻击保护。

(4)最后,重中之重,怎么保护 root key?无论是用哪种 envelope encryption的变种,都会涉及到怎么保护 root key。这是一个很有意思的话题,但篇幅关系就不展开来讲了。常见的有用 secret sharing的一些变种方式,也有通过公证人公证整个过程藏在银行保险箱的,也有藏在创始人地下室的:)怎么来 bootstrap 和 deploy 这个 root key 到加密服务里也是一个非常有意思和挑战的问题。

总的来说,数据加密不是一件神秘的事情,但要做好非常不容易,需要一定的技术积累和资源的投入。做任何一个安全系统,风险都不小。圈内人第一反应是怀疑,因为职业病;圈外人很多也觉得重要,但不关心,或者说不知道怎么关心。但不管如何,无论是因为潜在的法律风险还是用户的信任风险,这种安全上的投入从长期来说一定是值得的。

传送门:

1:Yahoo 2013年被盗超过10亿用户信息

2:Yahoo 2014年又被盗超过5亿用户信息

3:LinkedIn 被盗一亿多用户密码

4:Ashley Madison 被盗三千多万用户数据以及大量支付信息

5:Target 被盗近七千万用户数据和银行账号

6:Adobe 被盗三千八百万用户数据

7:RC4

8:MD5

9:Bcrypt 

10:KDF 

11:Rainbow Table Attack

12:Dictionary Attack

13:Message authentication code

14:Curve25519

15:secret sharing

雷锋网版权文章,未经授权禁止转载。详情见转载须知

    
  

本文作者: 朱赟

本文转自雷锋网禁止二次转载, 原文链接
目录
相关文章
|
5天前
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
|
8天前
|
Cloud Native Linux 开发者
【Docker】Docker:解析容器化技术的利器与在Linux中的关键作用
【Docker】Docker:解析容器化技术的利器与在Linux中的关键作用
|
5天前
|
供应链 Java API
Java 8新特性解析及应用区块链技术在供应链管理中的应用与挑战
【4月更文挑战第30天】本文将深入探讨Java 8的新特性,包括Lambda表达式、Stream API和Optional类等。通过对这些新特性的详细解析和应用实例,帮助读者更好地理解和掌握Java 8的新技术。
|
5天前
|
NoSQL 大数据 数据处理
MongoDB聚合框架与复杂查询优化:技术深度解析
【4月更文挑战第30天】本文深入探讨了MongoDB的聚合框架和复杂查询优化技术。聚合框架包含$match、$group、$sort和$project阶段,用于数据处理和分析,提供灵活性和高性能。优化查询涉及创建合适索引、使用聚合框架、简化查询语句、限制返回结果数、避免跨分片查询、只查询所需字段及使用$inc操作符。理解这些技术有助于提升MongoDB在大数据和复杂查询场景下的性能。
|
5天前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
|
6天前
|
编解码 前端开发 JavaScript
网页设计的艺术与技术:深入解析与代码实践
网页设计的艺术与技术:深入解析与代码实践
14 1
|
6天前
|
算法 计算机视觉 Python
DSP技术深度解析:原理、实践与应用
DSP技术深度解析:原理、实践与应用
15 1
|
7天前
|
前端开发 API UED
AngularJS的$http服务:深入解析与进行HTTP请求的技术实践
【4月更文挑战第28天】AngularJS的$http服务是核心组件,用于发起HTTP请求与服务器通信。$http服务简化了通信过程,通过深入理解和实践,能构建高效、可靠的前端应用。
|
9天前
|
存储 缓存 监控
|
10天前
|
Dart Java Android开发
Flutter插件开发:开发与使用的技术解析
【4月更文挑战第26天】本文详细介绍了Flutter插件开发,包括创建插件项目、编写原生代码(Android和iOS)、注册与使用插件。通过Flutter命令行工具生成插件,使用MethodChannel进行Dart与原生平台的通信。示例展示了如何获取设备信息并展示在Flutter应用中。文章还提到插件测试与发布,强调了兼容性与性能的重要性,指出Flutter插件是扩展应用功能的关键。

推荐镜像

更多