文档菜单
文档首页
/
MongoDB 手册
/ / / / /

CSFLE 加密模式

本页内容

  • 概述
  • 定义
  • 示例
  • 加密模式 - 多个字段
  • 加密模式 - 多个字段与继承
  • 加密模式 - 使用模式属性加密

注意

企业功能

字段级加密的自动功能仅在 MongoDB Enterprise 4.2 或更高版本以及 MongoDB Atlas 4.2 或更高版本的集群中可用。

加密模式包含用户指定的规则,用于标识哪些字段必须加密以及如何加密这些字段。应用程序必须使用 JSON Schema Draft 4 标准语法的严格子集以及以下加密特定关键字指定自动加密规则:JSON Schema Draft 4 标准和以下加密特定关键字

  • Encrypt指定加密当前字段时使用的加密选项。

  • Encrypt Metadata指定可继承的加密选项。

对于 MongoDB shell,请使用Mongo() 构造函数用于创建数据库连接,并包括客户端字段级加密作为配置对象的一部分。有关示例,请参阅配置对象。更多信息请参考启用客户端端加密的集群连接

对于官方MongoDB驱动程序,请使用特定于驱动的数据库连接构造函数(MongoClient)创建数据库连接,并将客户端字段级加密配置对象中的自动加密规则包含在内。有关CSFLE特定的MongoClient选项的更多信息,请参阅mongo客户端页面。

重要

不要在加密模式中指定文档验证关键字

**不要**在自动加密规则中指定文档验证关键字。要定义文档验证规则,请配置模式验证

encrypt

对象

"bsonType" : "object",
"properties" : {
"<fieldName>" : {
"encrypt" : {
"algorithm" : "<string>",
"bsonType" : "<string>" | [ "<string>" ],
"keyId" : [ <UUID> ]
}
}
}

表示必须加密的<fieldName>。`encrypt`对象有以下要求

  • encrypt 不能在 <fieldName> 对象中拥有任何兄弟字段。 encrypt 必须是 <fieldName> 对象的唯一子元素。

  • encrypt 不能在 itemsadditionalItems 关键字的任何子模式中指定。具体来说,自动客户端字段级加密不支持加密数组中的单个元素。

encrypt 对象可以包含 以下字段

如果将任何其他字段添加到 encrypt 对象中,则在执行自动加密读取或写入操作时会导致错误

如果省略了 keyIdalgorithm,则 自动加密共享库 会检查所有父字段,并尝试从最近的指定选项的 encryptMetadata 对象中构建这些选项。bsonType 不能继承,并且根据 algorithm 的值可能需要。

如果自动加密共享库无法使用指定的字段和任何必需的 encryptMetadata 继承的键构建完整的 encrypt 对象,则自动加密将失败并返回错误。

encrypt.algorithm

String

指示加密 <fieldName> 值时使用的加密算法。仅支持以下算法

  • AEAD_AES_256_CBC_HMAC_SHA_512-Random

  • AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic

有关加密算法的完整文档,请参阅 字段和加密类型。

如果省略,则自动加密共享库会检查所有父字段,寻找包含encryptMetadata.algorithm键的最接近祖先,并继承该值。如果不存在父级algorithm,自动字段级加密将失败并返回错误。

  • 如果encrypt.algorithm或其继承的值是AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic,则encrypt对象需要包含encrypt.bsonType字段。

  • 如果encrypt.algorithm或其继承的值是AEAD_AES_256_CBC_HMAC_SHA_512-Random,则encrypt对象可能包含encrypt.bsonType字段。

encrypt.bsonType

字符串 | 字符串数组

正在加密字段的BSON类型。如果encrypt.algorithmAEAD_AES_256_CBC_HMAC_SHA_512-Deterministic,则这是必需的。

如果encrypt.algorithm或其继承的值是AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic,则bsonType必须指定一个单个类型。对于确定性加密算法,bsonType不支持以下任何BSON类型:

  • double

  • decimal128

  • bool

  • object

  • array

如果encrypt.algorithm或其继承的值是AED_AES_256_CBC_HMAC_SHA_512-Random,则bsonType是可选的,可以指定支持的BSON类型的数组。对于具有bsonTypearrayobject的字段,客户端会加密整个数组或对象,而不是其单个元素。

encrypt.bsonType无论encrypt.algorithm或其继承的值如何,都不支持以下类型:

  • minKey

  • maxKey

  • null

  • undefined

encrypt.keyId

单一UUID数组

用于加密字段值的密钥数据的UUID。UUID是BSON 二进制数据元素,属于子类型4

在数组内指定一个字符串。

如果省略,则自动加密共享库会检查所有父字段,查找包含encryptMetadata.keyId键的最接近的祖先字段,并继承该值。如果父字段中不存在keyId键,则自动字段级加密失败并返回错误。

keyId或其继承的值必须存在于自动加密配置选项中指定的密钥库集合中。如果指定的数据加密密钥不存在,则自动加密失败。

官方MongoDB驱动程序对指定UUID有语言特定的要求。请参阅驱动程序文档以获取关于实现客户端字段级加密的完整文档。

encryptMetadata

对象

{
"bsonType" : "object",
"encryptMetadata" : {
"algorithm" : "<string>",
"keyId" : [ <UUID> ]
},
"properties" : {
"encrypt" : {}
}
}

定义了加密选项,一个嵌套在兄弟 properties 中的 encrypt 对象可以继承这些选项。如果 encrypt 对象缺少支持加密所需的选项,自动加密共享库将搜索所有父对象以定位一个指定缺少选项的 encryptMetadata 对象。

encryptMetadata 必须在具有 bsonType: "object" 的子模式中指定。encryptMetadata 不能指定给 itemsadditionalItems 关键字的任何子模式。具体来说,自动客户端字段级加密不支持加密数组中的单个元素。

encryptMetadata 对象可以包含 以下字段。向 encrypt 对象添加任何其他字段会导致自动加密读取或写入操作时出错

encryptMetadata.algorithm

String

用于加密特定字段的加密算法。如果encrypt对象缺少algorithm字段,自动加密共享库将在所有父对象中搜索,以定位指定encryptMetadata对象。

仅支持以下算法

  • AEAD_AES_256_CBC_HMAC_SHA_512-Random

  • AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic

关于加密算法的完整文档,请参阅字段和加密类型。

如果指定AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic,任何继承该值的encrypt对象必须指定encrypt.bsonType

encryptMetadata.keyId

单一UUID数组

数据加密键的UUID。UUID是BSON子类型4二进制数据元素。

在数组内指定一个字符串。

如果encrypt对象缺少keyId字段,自动加密共享库将在所有父对象中搜索,以定位指定encryptMetadata对象。

数据加密密钥必须在自动加密配置选项中指定的密钥库集合中存在。指定的配置选项还必须包括对密钥管理服务(KMS)和用于创建数据密钥的客户主密钥(CMK)的适当访问。如果数据加密密钥不存在或者客户端无法使用指定的KMS和CMK解密密钥,自动加密将失败。

官方MongoDB驱动程序对指定UUID有语言特定的要求。请参阅驱动程序文档以获取关于实现客户端字段级加密的完整文档。

考虑一个集合 MedCo.patients,其中每个文档具有以下结构

{
"fname" : "<String>",
"lname" : "<String>",
"passportId" : "<String>",
"bloodType" : "<String>",
"medicalRecords" : [
{<object>}
],
"insurance" : {
"policyNumber" : "<string>",
"provider" : "<string>"
}
}

以下字段包含可能被查询的个人身份信息(PII)

  • passportId

  • bloodType

  • insurance.policyNumber

  • insurance.provider

确定性的加密算法保证值的加密输出保持静态。这允许对特定值的查询返回有意义的成果,但代价是增加了对频率分析恢复的敏感性。因此,确定性的加密算法满足数据的加密和可查询性要求。

以下字段包含可能永远不会被查询的法律保护的个人信息(PII)

  • medicalRecords

随机的加密算法保证值的加密输出始终是唯一的。这防止了对特定字段值的查询返回有意义的成果,同时支持对字段内容最高级别的保护。因此,随机的加密算法满足数据的加密和可查询性要求。

以下架构指定了满足上述要求的自动加密规则,用于MedCo.patients集合

{
"MedCo.patients" : {
"bsonType" : "object",
"properties" : {
"passportId" : {
"encrypt" : {
"keyId" : [UUID("bffb361b-30d3-42c0-b7a4-d24a272b72e3")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
"bsonType" : "string"
}
},
"bloodType" : {
"encrypt" : {
"keyId" : [UUID("bffb361b-30d3-42c0-b7a4-d24a272b72e3")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
"bsonType" : "string"
}
},
"medicalRecords" : {
"encrypt" : {
"keyId" : [UUID("f3821212-e697-4d65-b740-4a6791697c6d")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
"bsonType" : "array"
}
},
"insurance" : {
"bsonType" : "object",
"properties" : {
"policyNumber" : {
"encrypt" : {
"keyId" : [UUID("bffb361b-30d3-42c0-b7a4-d24a272b72e3")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
"bsonType" : "string"
}
},
"provider" : {
"encrypt" : {
"keyId" : [UUID("bffb361b-30d3-42c0-b7a4-d24a272b72e3")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
"bsonType" : "string"
}
}
}
}
}
}
}

上述自动加密规则标记了需要加密的passportIdbloodTypeinsurance.policyNumberinsurance.providermedicalRecords字段。

  • passportIdbloodTypeinsurance.policyNumberprovider字段需要使用指定的密钥进行确定性加密。

  • medicalRecords字段需要使用指定的密钥进行随机加密。

虽然可查询加密不支持加密单个数组元素,但随机加密支持加密字段中的整个数组,而不是单个元素。示例自动加密规则指定了对medicalRecords字段进行随机加密以加密整个数组。如果自动加密规则在medicalRecords.itemsmedicalRecords.additionalItems中指定了encryptencryptMetadata,则自动字段级加密将失败并返回错误。

官方MongoDB驱动程序,mongosh和旧的mongo shell需要在创建数据库连接对象时指定自动加密规则。

  • 对于mongosh,使用Mongo()构造函数来创建数据库连接。将自动加密规则指定给AutoEncryptionOpts参数的schemaMap键。请参阅启用自动客户端加密的集群连接以获取完整示例。

  • 对于官方MongoDB驱动程序,使用特定于驱动程序的数据库连接构造函数(MongoClient)来创建包含查询加密配置对象中自动加密规则的数据库连接。请参阅驱动程序API参考以获取更完整的信息和教程。

对于所有客户端,指定给可查询加密参数的keyVaultkmsProviders必须授权访问自动加密规则中指定的数据加密密钥,以及用于加密数据加密密钥的客户主密钥。

考虑一个集合 MedCo.patients,其中每个文档具有以下结构

{
"fname" : "<String>",
"lname" : "<String>",
"passportId" : "<String>",
"bloodType" : "<String>",
"medicalRecords" : [
{<object>}
],
"insurance" : {
"policyNumber" : "<string>",
"provider" : "<string>"
}
}

以下字段包含可能被查询的私有数据

  • passportId

  • bloodType

  • insurance.policyNumber

  • insurance.provider

确定性的加密算法保证值的加密输出保持静态。这允许对特定值的查询返回有意义的成果,但代价是增加了对频率分析恢复的敏感性。因此,确定性的加密算法满足数据的加密和可查询性要求。

以下字段包含可能永远不会被查询的私有数据

  • medicalRecords

随机的加密算法保证值的加密输出始终是唯一的。这防止了对特定字段值的查询返回有意义的成果,同时支持对字段内容最高级别的保护。因此,随机的加密算法满足数据的加密和可查询性要求。

以下模式指定了自动加密规则,这些规则满足 MedCo.patients 集合的加密要求

{
"MedCo.patients" : {
"bsonType" : "object",
"encryptMetadata" : {
"keyId" : [UUID("6c512f5e-09bc-434f-b6db-c42eee30c6b1")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
},
"properties" : {
"passportId" : {
"encrypt" : {
"bsonType" : "string"
}
},
"bloodType" : {
"encrypt" : {
"bsonType" : "string"
}
},
"medicalRecords" : {
"encrypt" : {
"keyId" : [UUID("6c512f5e-09bc-434f-b6db-c42eee30c6b1")],
"algorithm" : "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
"bsonType" : "array"
}
},
"insurance" : {
"bsonType" : "object",
"properties" : {
"policyNumber" : {
"encrypt" : {
"bsonType" : "string"
}
},
"provider" : {
"encrypt" : {
"bsonType" : "string"
}
}
}
}
}
}
}

上述自动加密规则标记了需要加密的passportIdbloodTypeinsurance.policyNumberinsurance.providermedicalRecords字段。

  • passportIdbloodTypeinsurance.policyNumberprovider 字段从父 encryptMetadata 字段继承其加密设置。具体来说,这些字段继承指定数据加密密钥的确定加密的 algorithmkeyId 值。

  • medicalRecords 字段需要使用指定密钥进行随机加密。 encrypt 选项会覆盖父 encryptMetadata 字段中指定的选项。

虽然可查询加密不支持加密单个数组元素,但随机加密支持加密字段中的整个数组,而不是单个元素。示例自动加密规则指定了对medicalRecords字段进行随机加密以加密整个数组。如果自动加密规则在medicalRecords.itemsmedicalRecords.additionalItems中指定了encryptencryptMetadata,则自动字段级加密将失败并返回错误。

官方MongoDB驱动程序,mongosh和旧的mongo shell需要在创建数据库连接对象时指定自动加密规则。

  • 对于mongosh,使用Mongo()构造函数来创建数据库连接。将自动加密规则指定给AutoEncryptionOpts参数的schemaMap键。请参阅启用自动客户端加密的集群连接以获取完整示例。

  • 对于官方MongoDB驱动程序,使用特定于驱动程序的数据库连接构造函数(MongoClient)来创建包含查询加密配置对象中自动加密规则的数据库连接。请参阅驱动程序API参考以获取更完整的信息和教程。

对于所有客户端,指定给可查询加密参数的keyVaultkmsProviders必须授权访问自动加密规则中指定的数据加密密钥,以及用于加密数据加密密钥的客户主密钥。

有关更多关于您的密钥管理(CMK)和密钥保管库集合的信息,请参阅密钥保管库页面。

有关加密算法的更多信息,请参阅加密算法页面。

有关 CSFLE 特定的 MongoClient 选项的更多信息,请参阅Mongo 客户端页面。

您可以使用加密模式中的 patternProperties 关键字来定义与正则表达式匹配的所有字段的加密规则。

考虑一个集合 MedCo.patients,其中每个文档具有以下结构

{
"fname" : "<string>",
"lname" : "<string>",
"passportId_PIIString" : "<string>",
"bloodType_PIIString" : "<string>",
"medicalRecords_PIIArray" : [
{<object>}
],
"insurance" : {
"policyNumber_PIINumber" : "<number>",
"provider_PIIString" : "<string>"
}
}

包含私有数据的字段通过附加在字段名末尾的 "_PII<type>" 标签进行标识。

  • passportId_PIIString

  • bloodType_PIIString

  • medicalRecords_PIIArray

  • insurance.policyNumber_PIINumber

  • insurance.provider_PIIString

您可以使用 patternProperties 关键字来配置这些字段进行加密,而无需逐个标识每个字段,也不需要使用完整的字段名。通过使用匹配所有以 "_PII<type>" 标签结尾的字段的正则表达式来完成此操作。

以下 JSON 模式使用 patternProperties 和正则表达式来指定要加密的字段。

{
"MedCo.patients": {
"bsonType": "object",
"patternProperties": {
"_PIIString$": {
"encrypt": {
"keyId": [UUID("6c512f5e-09bc-434f-b6db-c42eee30c6b1")],
"bsonType": "string",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
"_PIIArray$": {
"encrypt": {
"keyId": [UUID("6c512f5e-09bc-434f-b6db-c42eee30c6b1")],
"bsonType": "array",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
},
},
"insurance": {
"bsonType": "object",
"patternProperties": {
"_PIINumber$": {
"encrypt": {
"keyId": [UUID("6c512f5e-09bc-434f-b6db-c42eee30c6b1")],
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
"_PIIString$": {
"encrypt": {
"keyId": [UUID("6c512f5e-09bc-434f-b6db-c42eee30c6b1")],
"bsonType": "string",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
},
},
},
},
}

上述自动加密规则将 passportId_PIIStringbloodType_PIIStringmedicalRecords_PIIArrayinsurance.policyNumber_PIINumberinsurance.provider_PIIString 字段标记为加密。

有关 patternProperties 关键字的更多信息,请参阅patternProperties 关键字。

返回

参考