暗号化 (CSFLE)
クライアント側暗号化は、アプリケーション内のデータを MongoDB に送信する前に暗号化する機能です。Spring Data による暗号化の適用を続行する前に、理想的には MongoDB ドキュメント (英語) から概念を理解し、その機能と制限について詳しく学ぶことをお勧めします。
クライアント側の暗号化を使用するようにドライバー |
自動暗号化
MongoDB は、自動暗号化機能を備えた MongoDB ドライバーを使用して、すぐに使えるクライアント側のフィールドレベル暗号化 (英語) をサポートします。自動暗号化には、明示的な暗号化 / 復号化の手順を行わなくても、暗号化された読み取りおよび書き込み操作を実行できる JSON スキーマが必要です。
暗号化情報を保持する 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);
};
}
明示的な暗号化
明示的な暗号化では、MongoDB ドライバーの暗号化ライブラリ (org.mongodb:mongodb-crypt
) を使用して暗号化タスクと復号化タスクを実行します。@ExplicitEncrypted
アノテーションは、JSON スキーマの作成とプロパティコンバーターに使用される @Encrypted
アノテーションを組み合わせたものです。言い換えれば、@ExplicitEncrypted
は既存のビルドブロックを使用して結合し、簡略化された明示的な暗号化サポートを実現します。
|
クライアント側のフィールドレベル暗号化を使用すると、決定的アルゴリズムとランダム化アルゴリズムのどちらかを選択できます。選択したアルゴリズム (英語) に応じて、異なる操作 (英語) がサポートされる場合があります。特定のアルゴリズムを選択するには、@ExplicitEncrypted(algorithm)
を使用します。アルゴリズム定数については、EncryptionAlgorithms
を参照してください。アルゴリズムとその使用箇所の詳細については、暗号化の種類 (英語) マニュアルを参照してください。
実際の暗号化を実行するには、データ暗号化キー (DEK) が必要です。キー管理の設定方法とデータ暗号化キーの作成方法の詳細については、MongoDB ドキュメント (英語) を参照してください。DEK は、id
または定義された別名を介して直接参照できます。@EncryptedField
アノテーションでは、代替名による DEK の参照のみが許可されます。後述する EncryptionKeyResolver
を任意の DEK に提供することが可能です。
@EncryptedField(algorithm=…, altKeyName = "secret-key") (1)
String ssn;
@EncryptedField(algorithm=…, altKeyName = "/name") (2)
String ssn;
1 | 代替名 secret-key で保存された DEK を使用します。 |
2 | 実際のフィールド値を読み取り、それをキー検索に使用するフィールド参照を使用します。保存操作には常に完全なドキュメントが存在する必要があります。フィールドはクエリ / 集計では使用できません。 |
デフォルトでは、@ExplicitEncrypted(value= …)
属性は MongoEncryptionConverter
を参照します。対応する型参照を提供することで、デフォルトの実装を変更し、任意の PropertyValueConverter
実装と交換することができます。カスタム PropertyValueConverters
と必要な構成の詳細については、"プロパティコンバーター - 特定のフィールドのマッピング" セクションを参照してください。
MongoEncryptionConverter セットアップ
MongoEncryptionConverter
のコンバーターのセットアップには、いくつかのコンポーネントが関係するため、いくつかの手順が必要です。Bean セットアップは以下で構成されます。
ClientEncryption
エンジンClientEncryption
およびEncryptionKeyResolver
で構成されたMongoEncryptionConverter
インスタンス。登録された
MongoEncryptionConverter
Bean を使用するPropertyValueConverterFactory
。
アノテーション付きキー解決を使用する副作用は、@ExplicitEncrypted
アノテーションで alt キー名を指定する必要がないことです。EncryptionKeyResolver
は、動的な DEK 解決を可能にするプロパティへのアクセスを提供する EncryptionContext
を使用します。
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 | com.mongodb.client.vault.ClientEncryption を使用して Encryption エンジンをセットアップします。インスタンスはステートフルであるため、使用後は閉じる必要があります。ClientEncryption は Closeable であるため、Spring がこれを処理します。 |
2 | アノテーションから EncryptionKey を決定するには、アノテーションベースの EncryptionKeyResolver をセットアップします。 |
3 | MongoEncryptionConverter を作成します。 |
4 | BeanFactory からの PropertyValueConverter ルックアップを有効にします。 |