此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data MongoDB 4.4.5! |
加密
Client Side Encryption 是一项功能,可在将应用程序中的数据发送到 MongoDB 之前对其进行加密。 我们建议您熟悉这些概念,最好从 MongoDB 文档中了解有关其功能和限制的更多信息,然后再继续通过 Spring Data 应用加密。
确保设置驱动程序 |
客户端字段级加密 (CSFLE)
选择 CSFLE 为您提供了充分的灵活性,并允许您为单个字段使用不同的键,例如。在“每个租户一个密钥”方案中。
在继续阅读之前,请务必查阅 MongoDB CSFLE 文档。
自动加密 (CSFLE)
MongoDB 使用 MongoDB 驱动程序及其自动加密功能支持开箱即用的客户端字段级加密。 自动加密需要一个 JSON 架构,该架构允许执行加密的读取和写入作,而无需提供显式的 en-/decryption 步骤。
请参阅 JSON 架构 有关定义包含加密信息的 JSON 架构的更多信息。
要使用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);
};
}
显式加密 (CSFLE)
显式加密使用 MongoDB 驱动程序的加密库 (org.mongodb:mongodb-crypt
) 执行加密和解密任务。
这@ExplicitEncrypted
annotation 是@Encrypted
用于 JSON 架构创建和属性转换器的注释。
换句话说,@ExplicitEncrypted
使用现有构建块将它们组合在一起,以实现简化的显式加密支持。
注释有 的字段
|
Client-Side Field Level Encryption 允许您在确定性算法和随机算法之间进行选择。根据所选的算法,可能支持不同的作。
要选择某种算法,请使用@ExplicitEncrypted(algorithm)
看EncryptionAlgorithms
对于算法常量。
请阅读 加密类型 手册 以了解有关算法及其用法的更多信息。
要执行实际加密,我们需要数据加密密钥 (DEK)。
有关如何设置密钥管理和创建数据加密密钥的更多信息,请参阅 MongoDB 文档。
DEK 可以通过其id
或定义的替代名称。
这@EncryptedField
annotation 只允许通过替代名称引用 DEK。
可以提供EncryptionKeyResolver
,这将在后面讨论,适用于任何 DEK。
@EncryptedField(algorithm=…, altKeyName = "secret-key") (1)
String ssn;
@EncryptedField(algorithm=…, altKeyName = "/name") (2)
String ssn;
1 | 使用与备用名称一起存储的 DEKsecret-key . |
2 | 使用字段引用,该引用将读取实际字段值并将其用于键查找。 始终要求存在完整的文档才能进行保存作。 字段不能用于查询/聚合。 |
默认情况下,@ExplicitEncrypted(value=…)
属性引用MongoEncryptionConverter
.
可以更改默认实现并将其与任何PropertyValueConverter
implementation 的 intent 的 intent 来提供相应的类型引用。
了解有关自定义的更多信息PropertyValueConverters
和所需的配置,请参阅 Property Converters - 映射特定字段 部分。
可查询加密 (QE)
选择 QE 使您能够对加密字段运行不同类型的查询,例如范围或相等性。
在继续阅读之前,请务必查阅 MongoDB QE 文档,以了解有关 QE 功能和限制的更多信息。
集合设置
Queryable Encryption 需要预先声明针对加密字段的实际查询中允许的某些方面。 该信息涵盖正在使用的算法以及允许的查询类型及其属性,必须在创建集合时提供。
MongoOperations#createCollection(…)
可用于对使用 QE 的集合进行初始设置。
通过 Spring Data 的 QE 配置使用与 CSFLE 相同的构建块(JSON 架构创建),将架构/属性转换为 MongoDB 所需的配置格式。
-
Manual Collection Setup
-
Derived Collection Setup
-
MongoDB Collection Info
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(…) 方法。 |
这Queryable
annotation 允许为加密字段定义允许的查询类型。@RangeEncrypted
是@Encrypted
和@Queryable
对于允许的字段range
查询。
可以从提供的 Comments 中创建自定义 Comments。
{
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)
MongoDB 使用 MongoDB 驱动程序及其自动加密功能支持开箱即用的可查询加密。 自动加密需要一个 JSON 架构,该架构允许执行加密的读取和写入作,而无需提供显式的 en-/decryption 步骤。
您需要做的就是根据 MongoDB 文档创建集合。 您可以使用技术来创建上一节中概述的所需配置。
MongoEncryptionConverter 设置
的转换器设置MongoEncryptionConverter
需要几个步骤,因为涉及多个组件。
Bean 设置包括以下内容:
-
这
ClientEncryption
发动机 -
一个
MongoEncryptionConverter
实例配置了ClientEncryption
以及EncryptionKeyResolver
. -
一个
PropertyValueConverterFactory
使用已注册的MongoEncryptionConverter
豆。
这EncryptionKeyResolver
使用EncryptionContext
提供对允许动态 DEK 解析的属性的访问。
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 | 设置Encryption engine 使用com.mongodb.client.vault.ClientEncryption .
该实例是有状态的,使用后必须关闭。
Spring 会处理这个问题,因为ClientEncryption 是Closeable . |
2 | 设置基于注释EncryptionKeyResolver 要确定EncryptionKey from annotations 中。 |
3 | 创建MongoEncryptionConverter . |
4 | Enable 的PropertyValueConverter 从BeanFactory . |