データは、セキュリティポリシー、コンプライアンス、および政府規制を満たすために、データトランザクションのほぼすべてのレベルでハイエンドのセキュリティを必要とすることがよくあります。機密データへの不正アクセスがあると、組織の評判が損なわれる可能性があります。そのため、概説されている義務を順守できません。
このブログでは、MongoDBに関して採用できるセキュリティ対策のいくつかについて、特にクライアント側に焦点を当てて説明します。
MongoDBデータカテゴリとその保護方法
一般に、データベースシステムには、次の2種類のデータが含まれます。
- 保存データ:データベースファイルに保存されているもの
- データ転送中:クライアント、サーバー、データベース間で処理されるデータ。
MongoDBには、ディスク上のデータベースファイルを暗号化するための暗号化機能があります。ディスク上のデータベースファイルへのアクセス。
ネットワークを介した転送中のデータは、データを暗号化することにより、TLS/SSLを使用したトランスポート暗号化を介してMongoDBで保護できます。
デスクトップ画面の受付係などのスタッフによってデータが誤って開示された場合、MongoDBはロールベースのアクセス制御を統合し、管理者がユーザーにコレクションレベルのアクセス許可を付与および制限できるようにします。
サーバー上で処理されたデータはメモリに残っている可能性があり、これらのアプローチは、サーバーメモリ内のデータアクセスに対するセキュリティ上の懸念に対処するものではありません。そのため、MongoDBは、機密データを含むドキュメントの特定のフィールドを暗号化するためのクライアント側フィールドレベル暗号化を導入しました。
MongoDBは、フィールドが定義されているドキュメントを処理します。一部のフィールドでは、クレジットカード番号、社会保障番号、忍耐力診断データなどの機密情報を保持する必要がある場合があります。
フィールドレベルの暗号化により、フィールドを保護できます。フィールドには、復号化キーを使用して許可された担当者のみがアクセスできます。
フィールドレベルの暗号化を適用する場合は、既存のデータベース設定ではなく、新しいデータベース設定を使用することを検討してください。
クライアント側フィールドレベル暗号化(CSFLE)
MongoDBバージョン4.2Enterpriseで導入され、データベース管理者がセキュリティで保護する必要のある値を含むフィールドを暗号化するための調整を提供します。つまり、機密データはクライアントによって暗号化または復号化され、暗号化された形式でサーバーとの間でのみ通信されます。さらに、暗号化キーを持たないスーパーユーザーでさえ、これらの暗号化されたデータフィールドを制御することはできません。
CSFLEの実装方法
クライアント側のフィールドレベルの暗号化を実装するには、次のものが必要です。
- MongoDBServer4.2エンタープライズ
- MongoDBはCSFLEと互換性があります
CSFLEの実装
CSFLEは、データ暗号化キーがマスターキーと呼ばれる別のキーで暗号化されるエンベロープ暗号化戦略を使用します。クライアントアプリケーションは、ローカルキープロバイダーに基本的にローカルファイルシステムに保存されるマスターキーを作成しますが、このストレージアプローチは安全ではないため、本番環境では、キーを保存するキー管理システム(KMS)でキーを構成することをお勧めします。データ暗号化キーをリモートで復号化します。
データ暗号化キーが生成された後、それらは暗号化されたデータと同じMongoDBレプリカセットのボールトコレクションに保存されます。
ノードjsで、96バイトのローカル管理マスターキーを生成し、メインスクリプトが実行されるディレクトリ内のファイルに書き込む必要があります。
$npm install fs && npm install crypto
次に、スクリプトで:
const crypto = require(“crypto”)
const fs = require(“fs”)
try{
fs.writeFileSync(‘masterKey.txt’, crypto.randomBytes(96))
}catch(err){
throw err;
}
このキーは、CSFLE対応のクライアントが暗号化/復号化のためにキーにアクセスできるキーボールトコレクションに保存されます。生成するには、次のものが必要です。
- データベースへの接続、つまりMongoDB接続文字列
- キーボールト名前空間(データベースとコレクション)
-
前に生成されたローカルマスターキーを読み取る
const localMasterKey = fs.readFileSync(‘./masterKey.txt’);
-
クライアントがマスターキーを検出するために使用するKMSプロバイダー設定を指定します。
const kmsProvider = {
local: {
key: localMasterKey
}
}
-
データ暗号化キーの作成。 MongoDB接続文字列とキーボールト名前空間構成を使用してクライアントを作成する必要があります。ユーザーというデータベースがあり、その中にkeyVaultコレクションがあるとします。コマンドを実行して、最初にuuid-base64をインストールする必要があります
$ npm install uuid-base64
次にスクリプトで
const base64 = require('uuid-base64');
const keyVaultNamespace = 'users.keyVaul';
const client = new MongoClient('mongodb://localhost:27017', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function createKey() {
try {
await client.connect();
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProvider,
});
const key = await encryption.createDataKey('local');
const base64DataKeyId = key.toString('base64');
const uuidDataKeyId = base64.decode(base64DataKeyId);
console.log('DataKeyId [UUID]: ', uuidDataKeyId);
console.log('DataKeyId [base64]: ', base64DataKeyId);
} finally {
await client.close();
}
}
createKey();
次に、次のような結果が表示されます
DataKeyId [UUID]: ad4d735a-44789-48bc-bb93-3c81c3c90824
DataKeyId [base64]: 4K13FkSZSLy7kwABP4HQyD==
クライアントには、指定されたキーボールト名前空間に対する読み取り/書き込み権限が必要です
-
データ暗号化キーが作成されたことを確認するには
const client = new MongoClient('mongodb://localhost:27017', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function checkClient() {
try {
await client.connect();
const keyDB = client.db(users);
const keyColl = keyDB.collection(keyVault);
const query = {
_id: ‘4K13FkSZSLy7kwABP4HQyD==’,
};
const dataKey = await keyColl.findOne(query);
console.log(dataKey);
} finally {
await client.close();
}
}
checkClient();
ある種の結果を受け取るはずです
{
_id: Binary {
_bsontype: 'Binary',
sub_type: 4,
position: 2,
buffer: <Buffer 68 ca d2 10 16 5d 45 bf 9d 1d 44 d4 91 a6 92 44>
},
keyMaterial: Binary {
_bsontype: 'Binary',
sub_type: 0,
position: 20,
buffer: <Buffer f1 4a 9f bd aa ac c9 89 e9 b3 da 48 72 8e a8 62 97 2a 4a a0 d2 d4 2d a8 f0 74 9c 16 4d 2c 95 34 19 22 05 05 84 0e 41 42 12 1e e3 b5 f0 b1 c5 a8 37 b8 ... 110 more bytes>
},
creationDate: 2020-02-08T11:10:20.021Z,
updateDate: 2020-02-08T11:10:25.021Z,
status: 0,
masterKey: { provider: 'local' }
}
返されるドキュメントデータには、データ暗号化キーID(UUID)、暗号化された形式のデータ暗号化キー、マスターキーのKMSプロバイダー情報、および日のようなメタデータが含まれます。作成。
JSONスキーマ拡張機能は、MongoDBドライバーによって使用され、コレクション内のドキュメントの指定されたフィールドの自動クライアント側暗号化と復号化を構成します。このスキーマのCSFLE構成には、各フィールドを暗号化するときに使用する暗号化アルゴリズム、CSFLEマスターキーで暗号化された1つまたはすべての暗号化キー、および各フィールドのBSONタイプが必要です。
ただし、このCSFLE JSONスキーマはドキュメントの検証をサポートしていません。サポートしていない場合、検証インスタンスによってクライアントがエラーをスローします。
適切なクライアント側のJSONスキーマで構成されていないクライアントは、サーバー側のJSONスキーマを使用して、暗号化されていないデータをフィールドに書き込むことを制限できます。
JSONスキーマのルートレベルでいくつかのencryptMetadataキーを定義し、スキーマのプロパティフィールドで定義することにより、暗号化されるフィールドで構成します。これにより、この暗号化キーを継承できるようになります。 。
{
"bsonType" : "object",
"encryptMetadata" : {
"keyId" : // keyId generated here
},
"properties": {
// field schemas here
}
}
銀行口座番号フィールドを暗号化するとします。次のようにします:
"bankAccountNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
カーディナリティが高く、フィールドがクエリ可能であるため、決定論的アプローチを使用します。クエリプランが低く、カーディナリティが低い血液型などの機密性の高いフィールドは、ランダムアプローチを使用して暗号化できます。
配列フィールドは、CSFLEによるランダム暗号化を使用して、すべての要素の自動暗号化を強化する必要があります。
Mongocryptedアプリケーション
MongoDB Enterprise Service 4.2以降にインストールされている、これは、クライアント側のフィールドレベルの暗号化を自動化する別個の暗号化アプリケーションです。 CSFLE対応のクライアントが作成されると、このサービスはデフォルトで自動的に次のように開始されます。
- JSONスキーマで概説されている暗号化命令を検証し、スループット操作で暗号化されるフィールドを検出します。
データを挿入するには、通常の挿入クエリを実行します。結果のドキュメントには、銀行口座フィールドに関する以下のサンプルデータが含まれます。
{
…
"bankAccountNumber":"Ac+ZbPM+sk7gl7CJCcIzlRAQUJ+uo/0WhqX+KbTNdhqCszHucqXNiwqEUjkGlh7gK8pm2JhIs/P3//nkVP0dWu8pSs6TJnpfUwRjPfnI0TURzQ==",
…
}
許可された担当者がクエリを実行すると、ドライバーはこのデータを復号化し、読み取り可能な形式で返します。つまり、
{
…
"bankAccountNumber":43265436456456456756,
…
}
注:ランダムに暗号化されたフィールドデータの近似値を含むドキュメントを見つけるために別のフィールドを使用しない限り、ランダムに暗号化されたフィールドのドキュメントをクエリすることはできません。
データのセキュリティは、休止中および転送中の1つに関して、すべてのレベルで考慮する必要があります。 MongoDB Enterprise 4.2 Serverは、クライアント側のフィールドレベル暗号化を使用してクライアント側からデータを暗号化するウィンドウを開発者に提供します。これにより、データベースホストプロバイダーからのデータと安全でないネットワークアクセスを保護します。 CSFLEはエンベロープ暗号化を使用し、マスターキーを使用してデータ暗号化キーを暗号化します。したがって、マスターキーは、キー管理システムなどのキー管理ツールを使用して安全に保管する必要があります。