このガイドでは、FS コア プロバイダーを使用して、 Queryable Encryption (QE)を使用して特定のドキュメントフィールドを暗号化する方法を学習できます。
Overview
Queryable Encryption は、 MongoDBにデータを書き込む前に、アプリケーションレイヤーの機密ドキュメントフィールドを暗号化すると同時に、アプリケーションがそれらのフィールドをクエリできるようにします。暗号化のキーにアクセスできるアプリケーションのみが、プレーンテキスト データを読み取ることができます。攻撃者がデータベースにアクセスできる場合、暗号化のキーにアクセスできないため、暗号化テキストのみが表示されます。
例、 では、 Queryable Encryption を使用して、次の内容を含むフィールドを暗号化できます。
ソーシャル セキュリティ番号
クレジット カード番号
医療情報または医療情報
金融情報
その他の機密情報や個人を特定できる情報
SF Core プロバイダーは、fluent モデルAPIを通じてQueryable Encryptionをサポートしています。暗号化するエンティティ プロパティは OnModelCreating() メソッドを使用して構成され、プロバイダーはデータの読み取りと書き込み時に暗号化を自動的に処理します。
前提条件
FS コア プロバイダーを使用してQueryable Encryptionを構成する前に、次の条件があることを確認してください。
MongoDB 7.0 以降を実行中MongoDB EnterpriseまたはMongoDB Atlasクラスター。
KMS(Key Management Service)へのアクセス。サポートされている KMS プロバイダーには、 Amazon Web Services、 Azure、 Google Cloud Platform、 Key Management Interoperability Protocol (KMIP)、ローカルキープロバイダーなどがあります。
環境にインストールされている 自動暗号化共有ライブラリ(
CRYPT_SHARED)またはmongocryptd。共有ライブラリをインストールする方法については、 MongoDB Serverドキュメントの「 クエリ分析コンポーネントのインストール 」を参照してください。
Queryable Encryption の有効化
次のセクションでは、コンテキストで暗号化オプションを構成し、モデルで暗号化用のエンティティ プロパティをマークする方法について説明します。
暗号化オプションの設定
Queryable Encryptionを使用するコンテキストを構成する前に、次のコードを実行中てアプリケーションの自動暗号化プロバイダーを 1 回登録する必要があります。
MongoClientSettings.Extensions.AddAutoEncryption();
次に、MongoOptionsExtensionインスタンスを作成し、そのインスタンスを UseMongoDB() メソッドに渡す前に、次のメソッドを連鎖させます。
WithKmsProviders()_ は、KMS プロバイダーと認証情報を指定します。WithKeyVaultNamespace()— データ暗号化キーの保存に使用されるコレクションを指定します。WithCryptProvider()— 使用する暗号化ライブラリとそのパスを指定します。
次の例では、開発用のローカル KMS プロバイダーを構成しています。
var kmsProviders = new Dictionary< string, IReadOnlyDictionary<string, object>> { { "local", new Dictionary<string, object> { { "key", localMasterKey } } } }; var keyVaultNamespace = CollectionNamespace.FromFullName( "encryption.__keyVault"); var mongoOptions = new MongoOptionsExtension() .WithConnectionString(connectionString) .WithDatabaseName("myDatabase") .WithKmsProviders(kmsProviders) .WithKeyVaultNamespace(keyVaultNamespace) .WithCryptProvider( CryptProvider.AutoEncryptSharedLibrary, Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH")); var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>() .UseMongoDB(mongoOptions);
共有ライブラリの代わりに mongocryptd を使用するには、CryptProvider.Mongocryptd と mongocryptd バイナリへのパスを WithCryptProvider() メソッドに渡します。
警告
本番環境ではローカル KMS プロバイダーを使用しないでください。リモート KMS を使用しないと、マスター キーへの不正アクセスや、データの復号に必要なキーの永続的な損失のリスクがあります。
暗号化のフィールドをマークする
OnModelCreating() メソッドで、暗号化するプロパティごとに暗号化メソッドを呼び出します。選択した方法によって、そのフィールドで使用できるクエリ タイプが制御されます。
方式 | クエリ サポート | ノート |
|---|---|---|
| なし | クエリ サポートなしでフィールドを暗号化します。保存するが直接フィルタリングしないフィールドには を使用します。 |
| 等価( |
|
| 範囲( |
|
スカラープロパティではなく、所有されているエンティティを暗号化するには、OwnsOne() または OwnsMany() から返された OwnedNavigationBuilder または OwnershipBuilder で IsEncrypted(dataKeyId) を呼び出します。
前述のメソッドを使用する完全な例については、「 例: クライアント データの暗号化 」セクションを参照してください。
例: パッチ データの暗号化
次の Patient エンティティは、暗号化する SSN フィールドと DateOfBirth フィールドを持つドキュメントモデルを定義します。
public class Patient { public ObjectId Id { get; set; } public string Name { get; set; } = null!; public string SSN { get; set; } = null!; public DateTime DateOfBirth { get; set; } }
次の HospitalContext は、OnModelCreating() メソッドで暗号化フィールドをマークします。 SSN はクエリ サポートなしで暗号化され、DateOfBirth は範囲クエリ サポート付きで暗号化されます。コンストラクターは、コンテキストを初期化する前にキーヴォールトで作成した 2 つのデータ暗号化キーの ID を受け入れます。
public class HospitalContext : DbContext { public DbSet<Patient> Patients { get; set; } = null!; private readonly Guid _ssnDataKeyId; private readonly Guid _dobDataKeyId; public HospitalContext( DbContextOptions options, Guid ssnDataKeyId, Guid dobDataKeyId) : base(options) { _ssnDataKeyId = ssnDataKeyId; _dobDataKeyId = dobDataKeyId; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Patient>(entity => { entity.ToCollection("patients"); entity.Property(p => p.SSN) .IsEncrypted(_ssnDataKeyId); entity.Property(p => p.DateOfBirth) .IsEncryptedForRange( new DateTime(1900, 1, 1), new DateTime(2100, 12, 31), _dobDataKeyId); }); } }
次のコードでは、暗号化オプションを構成し、データキー ID を使用して HospitalContext をインスタンス化し、Patientドキュメントを挿入してクエリを実行します。
var mongoOptions = new MongoOptionsExtension() .WithConnectionString("<connection string URI>") .WithDatabaseName("hospitalDb") .WithKmsProviders(kmsProviders) .WithKeyVaultNamespace(keyVaultNamespace) .WithCryptProvider( CryptProvider.AutoEncryptSharedLibrary, Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH")); using var context = new HospitalContext( new DbContextOptionsBuilder<HospitalContext>() .UseMongoDB(mongoOptions) .Options, ssnDataKeyId, dobDataKeyId); context.Database.EnsureCreated(); context.Patients.Add(new Patient { Name = "John Doe", SSN = "123-45-6789", DateOfBirth = new DateTime(1985, 6, 15) }); context.SaveChanges(); var results = context.Patients .Where(p => p.DateOfBirth > new DateTime(1980, 1, 1)) .ToList();
サーバーサイド スキーマのサポート
デフォルトでは 、SF コアプロバイダーはフィールド暗号化構成をクライアントにのみ適用します。クライアント専用の暗号化は、暗号化スキーマがまだ進行中の可能性がある開発中に適しています。
本番環境では、コレクションを作成する ときに、サーバー上の暗号化スキーマを登録します。サーバーにスキーマが保持されると、クライアント構成とは無関係に暗号化が強制され、誤って構成されたクライアントからの誤ったプレーンテキスト書込みを防止します。サーバーにスキーマを登録した後は、コレクションを再作成せずに、暗号化されるフィールドを変更できません。
サーバー側スキーマを使用してコレクションを作成するには、コンテキストの Model を QueryableEncryptionSchemaGenerator.GenerateSchemas() に渡します。次に、次の例に示すように、結果を CreateCollection() メソッドに渡します。
var encryptedSchemas = QueryableEncryptionSchemaGenerator.GenerateSchemas( context.Model); using var client = new MongoClient( "<connection string URI>"); var database = client.GetDatabase("hospitalDb"); foreach (var entityType in context.Model .GetEntityTypes() .Where(e => e.IsDocumentRoot())) { var collectionName = entityType.GetCollectionName(); if (encryptedSchemas.TryGetValue( collectionName, out var schema)) { database.CreateCollection( collectionName, new CreateCollectionOptions { EncryptedFields = schema }); } } context.Database.EnsureCreated();
暗号化されたコレクションがサーバーに存在したら、サーバースキーマのみを使用するように新しいコンテキスト インスタンスを構成できます。次の例に示すように、MongoOptionsExtension に QueryableEncryptionSchemaMode.Ignore を設定します。
var mongoOptions = new MongoOptionsExtension() .WithConnectionString("<connection string URI>") .WithDatabaseName("hospitalDb") .WithKmsProviders(kmsProviders) .WithKeyVaultNamespace(keyVaultNamespace) .WithCryptProvider( CryptProvider.AutoEncryptSharedLibrary, Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH")) .WithQueryableEncryptionSchemaMode( QueryableEncryptionSchemaMode.Ignore);
Ignoreモードでは、OnModelCreating() メソッドによる IsEncrypted の構成は暗号化には影響しません。サーバースキーマは、どのフィールドを暗号化するかを制御します。
詳細情報
Queryable Encryptionの詳細については、 MongoDB Serverマニュアルの「 Queryable Encryption 」および「 Queryable Encryptionのユースケース 」セクションを参照してください。
完全な実装の詳細については、 EM コア プロバイダーAPIドキュメント を参照してください。