_加密_是将一段信息从明文(信息的原始形式)转换为密码文本的过程,这是一种不可读的形式,只有拥有正确密码的人或计算机才能读取。如果一个恶意的行为者截获了一段加密数据,他们将无法阅读,直到他们能够解密它。
你可以通过配置MongoDB实例,使其要求使用_传输层安全_(也称为_TLS_)的连接,来加密MongoDB实例和任何需要访问它的客户端或应用程序之间的通信。就像它的前身_安全套接字层_(SSL)一样,TLS是一个加密协议,它使用基于证书的认证来加密在网络上传输的数据。
请注意,TLS只在数据在网络上移动时对其进行加密,也就是所谓的传输中的_数据_。即使你把Mongo配置成需要用TLS进行连接,存储在数据库服务器上的静态数据,称为_静态数据_,仍然是未加密的。MongoDB的免费社区版不可能对静态数据进行加密,但Mongo的付费订阅企业版可以做到。
不过,即使启用了静态加密和传输中加密,你的敏感数据仍有可能被未经批准的用户访问。例如,考虑这样一种情况:你已经部署了一个分片的NoSQL文档数据库来存储你所开发的冰淇淋配送应用的数据。数据库管理系统允许你对静态数据进行加密,你启用了这一功能,并且你还将其配置为需要在分片以及任何客户端之间进行加密的TLS连接。
在这个例子中,当客户下订单时,他们被要求提交一些敏感信息,如他们的家庭地址或他们的信用卡号码。然后,应用程序将这些信息写入数据库的一个文件中,就像这样。
{
"name" : "Sammy Shark",
"address" : {
"street" : "602 Surf Ave",
"city" : "Brooklyn",
"state" : "New York",
"zip" : 11224
},
"phone" : "555-555-1234",
"creditcard" : "1234567890123456"
}
这是一个潜在的安全漏洞,因为任何有权限访问数据库的人都可以看到并利用你客户的敏感信息。
为了帮助减轻这种类型的风险,自4.2版以来,官方MongoDB驱动程序允许你执行_客户端字段级加密_。这意味着,如果配置得当,应用程序可以在数据被发送到数据库之前对文档中的某些字段进行加密。一旦数据被写入数据库,只有能够提出正确的加密密钥的应用程序或客户端才能够解密并读取这些字段中的数据。否则,假设street,city,zip,phone, 和creditcard 字段在客户端已经被加密,那么数据文档将看起来类似于这样。
{
"name" : "Sammy Shark",
"address" : {
"street" : BinData(6,"eirefi3eid5feiZae9t+oot0noh9oovoch3=iethoh9t"),
"city" : BinData(6,"xiesoh+aiveez=ngee1yei+u0aijah2eeKu7jeeB=oGh"),
"state" : "New York"
"zip" : BinData(6,"CoYeve+ziemaehai=io1Iliehoh6rei2+oo5eic0aeCh")
},
"phone" : BinData6,"quas+eG4chuolau6ahq=i8ahqui0otaek7phe+Miexoo"),
"creditcard" : BinData6,"rau0Teez=iju4As9Eeyiu+h4coht=ukae8ahFah4aRo="),
}
MongoDB将加密的值存储为二进制数据,正如前面例子中的BinData 类标签所示。每个值中的6 代表数据存储的二进制子类型,并表示被编码的二进制数据的种类。被Mongo的客户端字段级加密的值总是使用子类型6 。