跳到主要内容

加密(CSFLE)

DeepSeek V3 中英对照 Encryption (CSFLE)

客户端加密(Client Side Encryption)是一项功能,它在数据发送到 MongoDB 之前在您的应用程序中对数据进行加密。我们建议您熟悉相关概念,最好通过 MongoDB 文档 了解更多关于其功能和限制的信息,然后再继续通过 Spring Data 应用加密。

备注

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

自动加密

MongoDB 通过其驱动程序中的自动加密功能,开箱即用地支持客户端字段级加密。自动加密需要一个 JSON Schema,该模式允许在不提供显式加密/解密步骤的情况下执行加密的读写操作。

请参阅 JSON Schema 部分以获取有关定义包含加密信息的 JSON Schema 的更多信息。

为了使用 MongoJsonSchema,需要将其与 AutoEncryptionSettings 结合,这可以通过 MongoClientSettingsBuilderCustomizer 来实现。

@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);
};
}
java

显式加密

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

备注

使用 @ExplicitEncrypted 注解的字段总是作为一个整体进行加密。考虑以下示例:

@ExplicitEncrypted()
String simpleValue; 1

@ExplicitEncrypted()
Address address; 2

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

@ExplicitEncrypted()
Map<..., ...> mapOfString; 4
java
  • 如果值不为 null,则加密简单类型的值,例如 String

  • 将整个 Address 对象及其所有嵌套字段作为 Document 进行加密。如果仅加密 Address 的部分字段,例如 Address#street,则需要在 Address 内的 street 字段上使用 @ExplicitEncrypted 注解。

  • Collection 类型的字段作为单个值进行加密,而不是逐个条目加密。

  • Map 类型的字段作为单个值进行加密,而不是作为键/值条目进行加密。

客户端字段级加密允许你在确定性和随机化算法之间进行选择。根据所选算法不同的操作可能会被支持。要选择特定的算法,请使用 @ExplicitEncrypted(algorithm),有关算法常量,请参见 EncryptionAlgorithms。请阅读加密类型手册,以获取有关算法及其用法的更多信息。

为了执行实际的加密操作,我们需要一个数据加密密钥(Data Encryption Key,简称 DEK)。关于如何设置密钥管理并创建数据加密密钥的更多信息,请参阅 MongoDB 文档。DEK 可以直接通过其 id 或定义的替代名称进行引用。@EncryptedField 注解仅允许通过替代名称引用 DEK。你可以提供一个 EncryptionKeyResolver(稍后将讨论)来解析任何 DEK。

示例 1. 引用数据加密密钥

@EncryptedField(algorithm=, altKeyName = "secret-key") 1
String ssn;
java
@EncryptedField(algorithm=, altKeyName = "/name")      2
String ssn;
java
  • 使用存储为替代名称 secret-key 的 DEK。

  • 使用字段引用,该引用将读取实际字段值并将其用于密钥查找。保存操作始终要求完整文档存在。字段不能用于查询/聚合操作。

默认情况下,@ExplicitEncrypted(value=…) 属性引用的是 MongoEncryptionConverter。通过提供相应的类型引用,可以更改默认实现并替换为任何 PropertyValueConverter 的实现。要了解更多关于自定义 PropertyValueConverter 及其所需配置的信息,请参阅 属性转换器 - 映射特定字段 部分。

MongoEncryptionConverter 设置

MongoEncryptionConverter 的转换器设置需要几个步骤,因为涉及到多个组件。Bean 的设置包括以下内容:

  1. ClientEncryption 引擎

  2. 一个配置了 ClientEncryptionEncryptionKeyResolverMongoEncryptionConverter 实例。

  3. 一个使用已注册的 MongoEncryptionConverter bean 的 PropertyValueConverterFactory

使用带注解的密钥解析的一个副作用是,@ExplicitEncrypted 注解不需要指定备用密钥名称。EncryptionKeyResolver 使用一个 EncryptionContext,该上下文提供了对属性的访问,从而实现动态 DEK(数据加密密钥)解析。

示例 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
}
}
java
  • 使用 com.mongodb.client.vault.ClientEncryption 设置一个 Encryption 引擎。该实例是有状态的,使用后必须关闭。Spring 会处理这一点,因为 ClientEncryption 实现了 Closeable 接口。

  • 设置一个基于注解的 EncryptionKeyResolver,用于从注解中确定 EncryptionKey

  • 创建 MongoEncryptionConverter

  • 启用从 BeanFactory 中查找 PropertyValueConverter 的功能。