深入MongoDB4.2新特性:字段级加密 Client-Side Field Level Encryption

MongoDB4.2已经发布,新增了几大特性,其中安全改进,提供了字段级加密 Client-Side Field Level Encryption加密新特性。今天我们来深入学习一下这个新特性,以及使用的场景。

1、MongoDB字段级加密新特性介绍

MongoDB4.2驱动程序也提供客户端字段级加密支持。
这种加密机制依赖于客户端代码实现。
1.1加密场景
作为使用过MySQL或者之前MongoDB数据库的同学,应该很容易理解,绝大部分的电商、银行、社交平台的数据库敏感字段都会考虑加密处理。例如:支付宝、微信、微博账号的密码、账户余额、银行卡账号、授权码等等。一些商品的进货价格,供货商联系方式等。
但是也有很多系统不会做加密,比如早期的12306数据库里的用户信息字段(后面已经修复漏洞)。
早期的做法,如果有加密字段的需求,都是在业务逻辑层,设计加密算法。
常见的做法,比如对商品原始价格加密,对称加密Key直接计算。或者变换方式处理。
这些通常要程序员写代码完成。

1.2数据库透明加密
现在一些先进的数据库都开始提供DB级别的加密支持,比如Oracle、SQL Server,阿里云MySQL,现在MongoDB也开始支持这个特性。
应用程序可以在通过网络将数据传输到服务器之前提前加密Document文档中的某些字段,比如商品的价格Price,或者用户账号的存款余额。
只有能够访问正确加密密钥的应用程序才能解密和读取受保护的数据。
删除加密密钥会将使用该密钥加密的所有数据呈现为永久不可读。

MongoDB集群使用TLS加密来保护传输中的数据。集群还使用MongoDB加密存储引擎来保护磁盘上的数据。
请思考以下安全场景:
A、员工具有集群及其主机的管理访问权限。员工的访问级别允许他们在解密状态下查看敏感数据。
B、第三方托管MongoDB集群。提供程序具有主机或数据库级安全漏洞,未授权方在解密状态下访问数据。
C、第三方数据分析公司可以访问包含私人,个人或机密数据。第三方公司将解密的数据加载到未经授权的各方可以访问的不安全的存储区中。

对于上面的每种情况,具有MongoDB群集或主机的特权访问权限的用户都可以绕过加密来读取私有的机密数据。
所以在写入服务器之前,我们使用客户端字段级加密新特性,可以保护数据,降低在网络传输中暴露数据或绕过磁盘加密窃取数据的风险。
2、用户文档加密字段例子
下面是一个用户Document文档数据的例子:

{
  "name" : "Frank Xu",
  "address" : {
    "street" : "1234前门外大街",
    "city" : "杭州",
    "zip" : 99999
  },
  "phone" : "123-45-6789",
  "age" : "18"
}

假设是一个恋爱交友网站,手机号、年龄是敏感字段,不希望泄露。
我们可以使用客户端字段级加密功能,专门加密敏感信息,如age和phone。 加密数据可以保存为具有子类型的二进制数据格式。

{
  "name" : "Frank Xu",
  "address" : {
    "street" : "1234 前门外大街",
    "city" : "杭州",
    "zip" : 99999
  },
  "phone" : BinData(6,"U2FsdGVkX1+CGIDGUnGgtS46+c7R5u17SwPDEmzyCbA="),
  "age" : BinData(6,"AaloEw285E3AnfjP+r8ph2YCvMI1+rWzpZK97tV6iz0jx")
}

那些黑客,无法访问所需密,因此这些非法的MongoDB服务器的用户无法解密加密过的字段。
MongoDB支持两种使用官方MongoDB 4.2兼容驱动程序进行客户端字段级加密的方法:

3、字段的显式(手动)加密方式
MongoDB4.2兼容驱动程序支持使用特定数据密钥和加密算法显式加密或解密字段。
应用程序必须修改与构造读写操作相关的任何代码,以通过驱动程序加密库包含加密/解密逻辑。应用程序负责根据每个操作选择适当的加密/解密数据密钥。

4、字段的自动加密方式
MongoDB 4.2 Enterprise 企业版扩展了4.2兼容的驱动程序加密支持,包括使用JSON模式语法的自动字段级加密。
应用程序必须修改驱动程序客户端对象配置代码以包括自动加密设置。
通过加密配置客户端对集群的所有读/写操作都将使用预定义的自动加密规则自动进行加密和解密。
之前的读和写操作相关的代码不需要额外的修改。
MongoDB客户端字段级加密仅支持加密文档中的单个字段。要加密整个文档,必须配置加密文档中的每个字段。

自动化字段加密 Automatic Field Level Encryption
自动化字段加密,只有MongoDB4.2 Enterprise企业版支持。

MongoDB 4.2驱动程序支持自动客户端字段级加密。配置为自动客户端字段级加密的应用程序识别文档中的特定字段以进行加密和解密。 4.2驱动程序使用为客户端指定的自动加密规则来识别加密字段及其关联的加密密钥。
对于写操作,4.2驱动程序在写入MongoDB数据库之前加密字段值。
对于读取操作,4.2驱动程序在发出读取操作之前加密查询中的字段值。
4.2仅当客户端可以访问用于保护字段的加密密钥时,驱动程序才能解密文档中返回的加密值。

在实例化客户端以启用自动客户端字段级加密时,应用程序必须指定以下组件参数:
A、存储数据密钥密钥库的MongoDB集群。
B、用于存储加密数据密钥的密钥库命名空间(。)。
C、密钥管理服务(KMS)提供程序用于管理客户主密钥(CMK)。 MongoDB使用CMK加密所有数据密钥,然后将其存储在密钥保管库中,只保留未加密的元数据。驱动程序需要访问KMS才能加密和解密受保护的字段或创建新的数据密钥。
D、使用JSON模式语法( JSON schema syntax)的每字段加密规则。

注意:兼容4.2的驱动程序使用仅限企业版的mongocryptd进程来解析JSON模式数据,并在读取或写入文档时应用加密规则。自动加密和解密需要mongocryptd进程来完成。

官方MongoDB4.2兼容驱动程序都引入了支持自动加密和数据密钥管理的新功能。特别的说明规则,请参阅官方文档。

5、加密算法
MongoDB字段级加密使用encrypt-then-MAC方法与确定性或随机初始化的向量相结合来加密字段值。MongoDB仅支持HMAC-SHA-512 MAC与AES-256-CBC加密算法的组合。

5.1确定性加密
确定性加密算法确保每次执行算法时给定输入值始终加密到相同的输出值。虽然确定性加密为读取操作提供了更大的支持,但具有低基数的加密数据易受频率分析恢复的影响。也就是所谓的撞库破解方式。大概率撞击高频秘钥。

对于未在读取操作中使用的敏感字段,应用程序可以使用随机加密来改进对频率分析恢复的保护。

5.2随机加密
随机加密算法确保每次执行算法时给定输入值始终加密得到不同的输出值。虽然随机加密提供了对数据机密性的最强保证,但它也阻止了必须对加密字段进行操作以评估查询的任何读取操作的支持。也就是对比多次加密值再进行其他操作的可能性。

随机加密也可以支持加密整个对象或数组。例如下面的例子文档:

{
 "personal_information" : {
   "age" : "123-45-6789",
   "credit_score" : 750,
   "credit_cards" : [ "1234-5678-9012-3456", "9876-5432-1098-7654"]
 },
 "phone_numbers" : [ "(010) 555-0153" ]
}

使用随机加密算法加密personal_information和phone_numbers字段会加密整个对象。虽然这可以保护嵌套在这些字段下的所有字段,但它也会阻止查询那些嵌套被加密的字段。
对于在读取操作中使用的敏感字段,应用程序必须使用确定性加密来改进对加密字段的读取支持。

6、加密组件
MongoDB客户端字段级加密使用以下组件:
A、用于存储和检索客户主密钥(CMK)的第三方密钥管理服务(KMS)。 MongoDB目前仅支持Amazon Web Services密钥管理服务。
或者,客户端字段级加密支持用于加密数据密钥的本地密钥文件。本地密钥文件数据密钥加密应仅用于开发或评估阶段,不要用于生产环境。
B、可选的服务器端JSON模式,用于指定加密验证规则。
C、存储数据密钥密钥库的MongoDB集群。密钥保管库群集可能与存储客户端加密数据的群集不同。
D、用于支持自动加密的mongocryptd守护程序。仅MongoDB Enterprise企业版支持。
E、libmongocrypt库,用于管理KMS和mongocryptd之间的加密,解密和通信。包含在MongoDB 4.2驱动程序。

下图说明了驱动程序与每个加密组件之间的关系:
深入MongoDB4.2新特性:字段级加密 Client-Side Field Level Encryption
mongocryptd
仅限MongoDB企业版
mongocryptd非常重要,是一个驱动程序生成的客户端进程,用于解析和验证JSON模式加密规则。 是自动字段加密和解密的必备组件。

MongoDB4.2驱动程序自动生成mongocryptd进程。 应用程序可以配置参数,来控制产生行为,不需要自己编译生成。 详细配置请参阅驱动程序文档,了解控制mongocryptd产生的特定参数和语法。

6.2驱动程序兼容性表
以下编程语言驱动程序版本中支持自动字段加密的:
A、Node 3.3.0-beta 1
B、Java 3.11.0-rc0

参考资料:https://docs.mongodb.com/manual/core/security-client-side-encryption/#automatic-field-level-encryption

作者简介:
徐雷,
1)MongoDB中文社区联席主席;
2)《MongoDB实战》第2版译者;
3)阿里云大学讲师;阿里云栖社区讲师;
4)目前就职于阿里巴巴,架构师。

上一篇:c# 纯代码方式创建快捷方式


下一篇:PLSQL 逻辑多线程