此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data MongoDB 4.4.5spring-doc.cadn.net.cn

加密

Client Side Encryption 是一项功能,可在将应用程序中的数据发送到 MongoDB 之前对其进行加密。 我们建议您熟悉这些概念,最好从 MongoDB 文档中了解有关其功能和限制的更多信息,然后再继续通过 Spring Data 应用加密。spring-doc.cadn.net.cn

确保设置驱动程序com.mongodb.AutoEncryptionSettings以使用客户端加密。 MongoDB 不支持对所有字段类型进行加密。 特定数据类型需要确定性加密以保留相等比较功能。spring-doc.cadn.net.cn

客户端字段级加密 (CSFLE)

选择 CSFLE 为您提供了充分的灵活性,并允许您为单个字段使用不同的键,例如。在“每个租户一个密钥”方案中。
在继续阅读之前,请务必查阅 MongoDB CSFLE 文档spring-doc.cadn.net.cn

自动加密 (CSFLE)

MongoDB 使用 MongoDB 驱动程序及其自动加密功能支持开箱即用的客户端字段级加密。 自动加密需要一个 JSON 架构,该架构允许执行加密的读取和写入作,而无需提供显式的 en-/decryption 步骤。spring-doc.cadn.net.cn

请参阅 JSON 架构 有关定义包含加密信息的 JSON 架构的更多信息。spring-doc.cadn.net.cn

要使用MongoJsonSchema它需要与AutoEncryptionSettings这可以做到,例如。通过MongoClientSettingsBuilderCustomizer.spring-doc.cadn.net.cn

@Bean
MongoClientSettingsBuilderCustomizer customizer(MappingContext mappingContext) {
    return (builder) -> {

        // ... keyVaultCollection, kmsProvider, ...

        MongoJsonSchemaCreator schemaCreator = MongoJsonSchemaCreator.create(mappingContext);
        MongoJsonSchema patientSchema = schemaCreator
            .filter(MongoJsonSchemaCreator.encryptedOnly())
            .createSchemaFor(Patient.class);

        AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
            .keyVaultNamespace(keyVaultCollection)
            .kmsProviders(kmsProviders)
            .extraOptions(extraOpts)
            .schemaMap(Collections.singletonMap("db.patient", patientSchema.schemaDocument().toBsonDocument()))
            .build();

        builder.autoEncryptionSettings(autoEncryptionSettings);
    };
}

显式加密 (CSFLE)

显式加密使用 MongoDB 驱动程序的加密库 (org.mongodb:mongodb-crypt) 执行加密和解密任务。 这@ExplicitEncryptedannotation 是@Encrypted用于 JSON 架构创建和属性转换器的注释。 换句话说,@ExplicitEncrypted使用现有构建块将它们组合在一起,以实现简化的显式加密支持。spring-doc.cadn.net.cn

注释有 的字段@ExplicitEncrypted始终作为整体加密。 请考虑以下示例:spring-doc.cadn.net.cn

@ExplicitEncrypted(…)
String simpleValue;        (1)

@ExplicitEncrypted(…)
Address address;           (2)

@ExplicitEncrypted(…)
List<...> list;            (3)

@ExplicitEncrypted(…)
Map<..., ...> mapOfString; (4)
1 加密简单类型的值,例如String如果不是null.
2 加密整个Addressobject 及其所有嵌套字段作为Document. 要仅加密Address喜欢Address#streetstreet字段中Address需要注释@ExplicitEncrypted.
3 Collection-like 字段被加密为单个值,而不是按条目加密。
4 Map-like 字段被加密为单个值,而不是键/值条目。

Client-Side Field Level Encryption 允许您在确定性算法和随机算法之间进行选择。根据所选的算法,可能支持不同的作。 要选择某种算法,请使用@ExplicitEncrypted(algorithm)EncryptionAlgorithms对于算法常量。 请阅读 加密类型 手册 以了解有关算法及其用法的更多信息。spring-doc.cadn.net.cn

要执行实际加密,我们需要数据加密密钥 (DEK)。 有关如何设置密钥管理和创建数据加密密钥的更多信息,请参阅 MongoDB 文档。 DEK 可以通过其id或定义的替代名称。 这@EncryptedFieldannotation 只允许通过替代名称引用 DEK。 可以提供EncryptionKeyResolver,这将在后面讨论,适用于任何 DEK。spring-doc.cadn.net.cn

示例 1.引用数据加密密钥
@EncryptedField(algorithm=…, altKeyName = "secret-key") (1)
String ssn;
@EncryptedField(algorithm=…, altKeyName = "/name")      (2)
String ssn;
1 使用与备用名称一起存储的 DEKsecret-key.
2 使用字段引用,该引用将读取实际字段值并将其用于键查找。 始终要求存在完整的文档才能进行保存作。 字段不能用于查询/聚合。

默认情况下,@ExplicitEncrypted(value=…)属性引用MongoEncryptionConverter. 可以更改默认实现并将其与任何PropertyValueConverterimplementation 的 intent 的 intent 来提供相应的类型引用。 了解有关自定义的更多信息PropertyValueConverters和所需的配置,请参阅 Property Converters - 映射特定字段 部分。spring-doc.cadn.net.cn

可查询加密 (QE)

选择 QE 使您能够对加密字段运行不同类型的查询,例如范围相等性。
在继续阅读之前,请务必查阅 MongoDB QE 文档,以了解有关 QE 功能和限制的更多信息。spring-doc.cadn.net.cn

集合设置

Queryable Encryption 需要预先声明针对加密字段的实际查询中允许的某些方面。 该信息涵盖正在使用的算法以及允许的查询类型及其属性,必须在创建集合时提供。spring-doc.cadn.net.cn

MongoOperations#createCollection(…​)可用于对使用 QE 的集合进行初始设置。 通过 Spring Data 的 QE 配置使用与 CSFLE 相同的构建块(JSON 架构创建),将架构/属性转换为 MongoDB 所需的配置格式。spring-doc.cadn.net.cn

CollectionOptions collectionOptions = CollectionOptions.encryptedCollection(options -> options
	.queryable(encrypted(string("ssn")).algorithm("Indexed"), equality().contention(0))
	.queryable(encrypted(int32("age")).algorithm("Range"), range().contention(8).min(0).max(150))
	.queryable(encrypted(int64("address.sign")).algorithm("Range"), range().contention(2).min(-10L).max(10L))
);

mongoTemplate.createCollection(Patient.class, collectionOptions); (1)
1 使用模板创建集合可能会阻止捕获生成的 keyId。在这种情况下,渲染Document,然后使用createEncryptedCollection(…​)方法。
class Patient {

    @Id String id;

    @Encrypted(algorithm = "Indexed") //
    @Queryable(queryType = "equality", contentionFactor = 0)
    String ssn;

    @RangeEncrypted(contentionFactor = 8, rangeOptions = "{ 'min' : 0, 'max' : 150 }")
    Integer age;

    Address address;
}

MongoJsonSchema patientSchema = MongoJsonSchemaCreator.create(mappingContext)
    .filter(MongoJsonSchemaCreator.encryptedOnly())
    .createSchemaFor(Patient.class);

CollectionOptions collectionOptions = CollectionOptions.encryptedCollection(patientSchema);

mongoTemplate.createCollection(Patient.class, collectionOptions); (1)
1 使用模板创建集合可能会阻止捕获生成的 keyId。在这种情况下,渲染Document,然后使用createEncryptedCollection(…​)方法。

Queryableannotation 允许为加密字段定义允许的查询类型。@RangeEncrypted@Encrypted@Queryable对于允许的字段range查询。 可以从提供的 Comments 中创建自定义 Comments。spring-doc.cadn.net.cn

{
    name: 'patient',
    type: 'collection',
    options: {
      encryptedFields: {
        escCollection: 'enxcol_.test.esc',
        ecocCollection: 'enxcol_.test.ecoc',
        fields: [
          {
            keyId: ...,
            path: 'ssn',
            bsonType: 'string',
            queries: [ { queryType: 'equality', contention: Long('0') } ]
          },
          {
            keyId: ...,
            path: 'age',
            bsonType: 'int',
            queries: [ { queryType: 'range', contention: Long('8'), min: 0, max: 150 } ]
          },
          {
            keyId: ...,
            path: 'address.sign',
            bsonType: 'long',
            queries: [ { queryType: 'range', contention: Long('2'), min: Long('-10'), max: Long('10') } ]
          }
        ]
      }
    }
}
  • 不能在同一集合中同时使用 QE 和 CSFLE。spring-doc.cadn.net.cn

  • 无法查询rangeindexed 字段,其中equality算子。spring-doc.cadn.net.cn

  • 无法查询equality索引字段,其中range算子。spring-doc.cadn.net.cn

  • 无法设置bypassAutoEncrytion(true).spring-doc.cadn.net.cn

  • 无法通过以下方式使用自行维护的加密密钥@Encrypted与 Queryable Encryption 结合使用。spring-doc.cadn.net.cn

  • 争用在服务器端是可选的,客户端需要你设置值(默认为 us8).spring-doc.cadn.net.cn

  • 其他选项,例如minmax需要匹配实际的字段类型。请务必使用$numberLong等,以确保解析 bson String 时的目标类型。spring-doc.cadn.net.cn

  • Queryable Encryption 将增加一个字段safeContent添加到您的每个文档中。 除非明确排除,否则在检索结果时,该字段将被加载到内存中。spring-doc.cadn.net.cn

自动加密 (QE)

MongoDB 使用 MongoDB 驱动程序及其自动加密功能支持开箱即用的可查询加密。 自动加密需要一个 JSON 架构,该架构允许执行加密的读取和写入作,而无需提供显式的 en-/decryption 步骤。spring-doc.cadn.net.cn

您需要做的就是根据 MongoDB 文档创建集合。 您可以使用技术来创建上一节中概述的所需配置。spring-doc.cadn.net.cn

显式加密 (QE)

显式加密使用 MongoDB 驱动程序的加密库 (org.mongodb:mongodb-crypt) 根据域模型内 annotation 提供的元信息执行加密和解密任务。spring-doc.cadn.net.cn

没有官方支持使用显式可查询加密。 大胆的用户可能会结合@Encrypted@Queryable@ValueConverter(MongoEncryptionConverter.class)风险自负。spring-doc.cadn.net.cn

MongoEncryptionConverter 设置

的转换器设置MongoEncryptionConverter需要几个步骤,因为涉及多个组件。 Bean 设置包括以下内容:spring-doc.cadn.net.cn

  1. ClientEncryption发动机spring-doc.cadn.net.cn

  2. 一个MongoEncryptionConverter实例配置了ClientEncryption以及EncryptionKeyResolver.spring-doc.cadn.net.cn

  3. 一个PropertyValueConverterFactory使用已注册的MongoEncryptionConverter豆。spring-doc.cadn.net.cn

EncryptionKeyResolver使用EncryptionContext提供对允许动态 DEK 解析的属性的访问。spring-doc.cadn.net.cn

示例 2.MongoEncryptionConverter 配置示例
class Config extends AbstractMongoClientConfiguration {

    @Autowired ApplicationContext appContext;

    @Bean
    ClientEncryption clientEncryption() {                                                            (1)
        ClientEncryptionSettings encryptionSettings = ClientEncryptionSettings.builder();
        // …

        return ClientEncryptions.create(encryptionSettings);
    }

    @Bean
    MongoEncryptionConverter encryptingConverter(ClientEncryption clientEncryption) {

        Encryption<BsonValue, BsonBinary> encryption = MongoClientEncryption.just(clientEncryption);
        EncryptionKeyResolver keyResolver = EncryptionKeyResolver.annotated((ctx) -> …);             (2)

        return new MongoEncryptionConverter(encryption, keyResolver);                                (3)
    }

    @Override
    protected void configureConverters(MongoConverterConfigurationAdapter adapter) {

        adapter
            .registerPropertyValueConverterFactory(PropertyValueConverterFactory.beanFactoryAware(appContext)); (4)
    }
}
1 设置Encryptionengine 使用com.mongodb.client.vault.ClientEncryption. 该实例是有状态的,使用后必须关闭。 Spring 会处理这个问题,因为ClientEncryptionCloseable.
2 设置基于注释EncryptionKeyResolver要确定EncryptionKeyfrom annotations 中。
3 创建MongoEncryptionConverter.
4 Enable 的PropertyValueConverterBeanFactory.