Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ / / /

빠른 시작

이 페이지의 내용

  • 개요
  • 시작하기 전에
  • 절차
  • 고객 마스터 키 생성
  • 키 볼트 collection에 고유 인덱스 만들기
  • 데이터 암호화 키 생성
  • MongoClient 구성
  • 암호화된 필드가 있는 문서 삽입하기
  • 암호화된 필드로 문서 검색하기
  • 자세히 알아보기

이 가이드에서는 자동 CSFLE(클라이언트 측 필드 레벨 암호화) 및 MongoDB 드라이버를 사용하여 문서를 암호화하는 방법을 보여줍니다.

이 가이드를 완료한 후에는 다음 지식과 소프트웨어를 갖게 됩니다.

  • 문서의 필드를 암호화하도록 드라이버를 구성하는 단계를 이해합니다.

  • 작동하지만 프로덕션 준비가 되지 않은 클라이언트 애플리케이션으로 자동 클라이언트 측 필드 레벨 암호화를 활용합니다.

중요

이 애플리케이션을 프로덕션 환경에서는 사용하지 마세요.

이 예제 애플리케이션은 애플리케이션의 파일 시스템에 암호화 키를 저장하므로 키에 무단으로 액세스하거나 데이터를 해독하기 위한 키를 분실할 위험이 있습니다.

프로덕션 환경에서 사용할 수 있는 CSFLE 지원 애플리케이션을 만드는 방법을 보여주는 튜토리얼을 보려면 튜토리얼을 참조하세요 .

이 가이드의 코드를 완료하고 실행하려면 설치 요구 사항 페이지에 표시된 대로 개발 환경을 설정해야 합니다.

페이지 오른쪽의 Select your language 드롭다운 메뉴에서 코드 예제를 보려는 프로그래밍 언어를 선택합니다.

참조: 전체 적용

이 튜토리얼의 실행 가능한 전체 애플리케이션 코드를 보려면 다음 링크로 이동하십시오.

C# 애플리케이션 완성

// You are viewing the C# driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the Golang driver code examples.
// Use the dropdown menu to select a different driver.

중요

go build 또는 go run 를 사용하여 이 가이드의 Golang 코드를 빌드하거나 실행할 때는 항상 cse 빌드 제약 조건을 포함하여 CSFLE를 활성화하세요. 빌드 제약 조건을 포함하는 예는 다음 셸 명령을 참조하세요.

go run -tags cse insert-encrypted-document.go
// You are viewing the Java synchronous driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the Node.js driver code examples.
// Use the dropdown menu to select a different driver.
# You are viewing the Python driver code examples.
# Use the dropdown menu to select a different driver.
1

CSFLE를 수행하려면 고객 마스터 키(CMK)를 생성해야 합니다.

96바이트 고객 마스터 키를 생성하고 파일 시스템인 로컬 키 제공자master-key.txt 파일로 저장합니다.

const fs = require("fs");
const crypto = require("crypto");
try {
fs.writeFileSync("master-key.txt", crypto.randomBytes(96));
} catch (err) {
console.error(err);
}
using (var randomNumberGenerator = System.Security.Cryptography.RandomNumberGenerator.Create())
{
var bytes = new byte[96];
randomNumberGenerator.GetBytes(bytes);
var localMasterKeyBase64Write = Convert.ToBase64String(bytes);
Console.WriteLine(localMasterKeyBase64Write);
File.WriteAllText("master-key.txt", localMasterKeyBase64Write);
}
func localMasterKey() []byte {
key := make([]byte, 96)
if _, err := rand.Read(key); err != nil {
log.Fatalf("Unable to create a random 96 byte data key: %v", err)
}
if err := ioutil.WriteFile("master-key.txt", key, 0644); err != nil {
log.Fatalf("Unable to write key to file: %v", err)
}
return key
}
byte[] localMasterKeyWrite = new byte[96];
new SecureRandom().nextBytes(localMasterKeyWrite);
try (FileOutputStream stream = new FileOutputStream("master-key.txt")) {
stream.write(localMasterKeyWrite);
}
import os
path = "master-key.txt"
file_bytes = os.urandom(96)
with open(path, "wb") as f:
f.write(file_bytes)

경고

프로덕션 환경에서 로컬 키 파일을 사용하지 마세요.

파일 시스템의 로컬 키 파일은 안전하지 않으므로 프로덕션에 권장되지 않습니다 . 대신 원격 키 관리 시스템 에 고객 마스터 키를 저장해야 합니다. (KMS ).

Queryable Encryption 구현에서 원격 KMS 를 사용하는 방법을 알아보려면 튜토리얼 가이드를 참조하세요.

명령줄에서 고객 마스터 키 생성

Unix shell 또는 PowerShell에서 고객 마스터 키 를 생성하려면 다음 명령을 사용합니다.

  • Unix shell:

    echo $(head -c 96 /dev/urandom | base64 | tr -d '\n')
  • PowerShell:

    $r=[byte[]]::new(64);$g=[System.Security.Cryptography.RandomNumberGenerator]::Create();$g.GetBytes($r);[Convert]::ToBase64String($r)

이전 명령의 출력을 customer-master-key.txt 파일에 저장합니다.

참조: 코드 완성

고객 마스터 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

고객 마스터 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

고객 마스터 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

고객 마스터 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

고객 마스터 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

2

encryption.__keyVault 네임스페이스의 keyAltNames 필드에 부분 고유 인덱스를 생성합니다. 이 인덱스는 keyAltNames 가 존재하는 문서에 대해 partialFilterExpression 을 가져야 합니다.

클라이언트 측 필드 수준 암호화는 서버에서 적용되는 키 대체 이름의 고유성에 따라 달라집니다.

선호하는 MongoDB 드라이버에 해당하는 탭을 선택합니다:

var connectionString = "<Your MongoDB URI>";
var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
var keyVaultClient = new MongoClient(connectionString);
var indexOptions = new CreateIndexOptions<BsonDocument>();
indexOptions.Unique = true;
indexOptions.PartialFilterExpression = new BsonDocument { { "keyAltNames", new BsonDocument { { "$exists", new BsonBoolean(true) } } } };
var builder = Builders<BsonDocument>.IndexKeys;
var indexKeysDocument = builder.Ascending("keyAltNames");
var indexModel = new CreateIndexModel<BsonDocument>(indexKeysDocument, indexOptions);
var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.ToString());
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
keyVaultClient.GetDatabase("medicalRecords").DropCollection("patients");
var keyVaultCollection = keyVaultDatabase.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName.ToString());
keyVaultCollection.Indexes.CreateOne(indexModel);
uri := "<Your MongoDB URI>"
keyVaultClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
if err != nil {
return fmt.Errorf("Connect error for regular client: %v", err)
}
defer func() {
_ = keyVaultClient.Disconnect(context.TODO())
}()
keyVaultColl := "__keyVault"
keyVaultDb := "encryption"
keyVaultNamespace := keyVaultDb + "." + keyVaultColl
keyVaultIndex := mongo.IndexModel{
Keys: bson.D{{"keyAltNames", 1}},
Options: options.Index().
SetUnique(true).
SetPartialFilterExpression(bson.D{
{"keyAltNames", bson.D{
{"$exists", true},
}},
}),
}
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
if err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Drop(context.TODO()); err != nil {
log.Fatalf("Collection.Drop error: %v", err)
}
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
if err = keyVaultClient.Database("medicalRecords").Collection("patients").Drop(context.TODO()); err != nil {
log.Fatalf("Collection.Drop error: %v", err)
}
_, err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Indexes().CreateOne(context.TODO(), keyVaultIndex)
if err != nil {
panic(err)
}
String connectionString = "<Your MongoDB URI>";
String keyVaultDb = "encryption";
String keyVaultColl = "__keyVault";
String keyVaultNamespace = keyVaultDb + "." + keyVaultColl;
MongoClient keyVaultClient = MongoClients.create(connectionString);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl).drop();
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
keyVaultClient.getDatabase("medicalRecords").getCollection("patients").drop();
MongoCollection keyVaultCollection = keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl);
IndexOptions indexOpts = new IndexOptions().partialFilterExpression(new BsonDocument("keyAltNames", new BsonDocument("$exists", new BsonBoolean(true) ))).unique(true);
keyVaultCollection.createIndex(new BsonDocument("keyAltNames", new BsonInt32(1)), indexOpts);
keyVaultClient.close();
const uri = "<Your Connection String>";
const keyVaultDatabase = "encryption";
const keyVaultCollection = "__keyVault";
const keyVaultNamespace = `${keyVaultDatabase}.${keyVaultCollection}`;
const keyVaultClient = new MongoClient(uri);
await keyVaultClient.connect();
const keyVaultDB = keyVaultClient.db(keyVaultDatabase);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
await keyVaultDB.dropDatabase();
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
await keyVaultClient.db("medicalRecords").dropDatabase();
const keyVaultColl = keyVaultDB.collection(keyVaultCollection);
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{
unique: true,
partialFilterExpression: { keyAltNames: { $exists: true } },
}
);
connection_string = "<your connection string here>"
key_vault_coll = "__keyVault"
key_vault_db = "encryption"
key_vault_namespace = f"{key_vault_db}.{key_vault_coll}"
key_vault_client = MongoClient(connection_string)
# Drop the Key Vault Collection in case you created this collection
# in a previous run of this application.
key_vault_client.drop_database(key_vault_db)
# Drop the database storing your encrypted fields as all
# the DEKs encrypting those fields were deleted in the preceding line.
key_vault_client["medicalRecords"].drop_collection("patients")
key_vault_client[key_vault_db][key_vault_coll].create_index(
[("keyAltNames", ASCENDING)],
unique=True,
partialFilterExpression={"keyAltNames": {"$exists": True}},
)
3
1

이 가이드의 고객 마스터 키 생성 단계에서 생성한 고객 마스터 키 파일의 내용을 조회합니다.

고객 마스터 키 값을 KMS 제공자 설정으로 전달합니다. 클라이언트는 이러한 설정을 사용하여 고객 마스터 키 를 검색합니다. 로컬 키 제공자를 사용하려면 제공자 이름을 local 로 설정합니다.

var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
var provider = "local";
string localMasterKeyBase64Read = File.ReadAllText("master-key.txt");
var localMasterKeyBytes = Convert.FromBase64String(localMasterKeyBase64Read);
var localOptions = new Dictionary<string, object>
{
{ "key", localMasterKeyBytes }
};
kmsProviders.Add("local", localOptions);
key, err := ioutil.ReadFile("master-key.txt")
if err != nil {
log.Fatalf("Could not read the key from master-key.txt: %v", err)
}
provider := "local"
kmsProviders := map[string]map[string]interface{}{"local": {"key": key}}
String kmsProvider = "local";
String path = "master-key.txt";
byte[] localMasterKeyRead = new byte[96];
try (FileInputStream fis = new FileInputStream(path)) {
if (fis.read(localMasterKeyRead) < 96)
throw new Exception("Expected to read 96 bytes from file");
}
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put("key", localMasterKeyRead);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
kmsProviders.put("local", keyMap);
const provider = "local";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
path = "./master-key.txt"
with open(path, "rb") as f:
local_master_key = f.read()
kms_providers = {
"local": {
"key": local_master_key # local_master_key variable from the previous step
},
}
2

MongoDB 연결 문자열과 키 볼트 컬렉션 네임스페이스를 사용하여 클라이언트를 구성하고 데이터 암호화 키를 만듭니다.

참고

키 볼트 컬렉션 네임스페이스 권한

이 튜토리얼을 완료하려면 애플리케이션에서 MongoDB에 연결하는 데 사용하는 데이터베이스 사용자에게 다음 네임스페이스에 대한 dbAdmin 권한이 있어야 합니다.

  • encryption.__keyVault

  • medicalRecords database

var clientEncryptionOptions = new ClientEncryptionOptions(
keyVaultClient: keyVaultClient,
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders
);
var clientEncryption = new ClientEncryption(clientEncryptionOptions);
var dataKeyOptions = new DataKeyOptions();
var dataKeyId = clientEncryption.CreateDataKey(provider, dataKeyOptions, CancellationToken.None);
var dataKeyIdBase64 = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));
Console.WriteLine($"DataKeyId [base64]: {dataKeyIdBase64}");
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(keyVaultNamespace).
SetKmsProviders(kmsProviders)
clientEnc, err := mongo.NewClientEncryption(keyVaultClient, clientEncryptionOpts)
if err != nil {
return fmt.Errorf("NewClientEncryption error %v", err)
}
defer func() {
_ = clientEnc.Close(context.TODO())
}()
dataKeyOpts := options.DataKey()
dataKeyID, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts)
if err != nil {
return fmt.Errorf("create data key error %v", err)
}
fmt.Printf("DataKeyId [base64]: %s\n", base64.StdEncoding.EncodeToString(dataKeyID.Data))
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
MongoClient regularClient = MongoClients.create(connectionString);
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions());
String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
System.out.println("DataKeyId [base64]: " + base64DataKeyId);
clientEncryption.close();
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
await client.connect();
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProviders,
});
const key = await encryption.createDataKey(provider);
console.log("DataKeyId [base64]: ", key.toString("base64"));
await keyVaultClient.close();
await client.close();

참고

클라이언트 암호화 가져오기

Node.js 드라이버 v6.0 이상을 사용하는 경우 mongodb에서 ClientEncryption을(를) 가져와야 합니다.

이전 드라이버 버전의 경우 mongodb-client-encryption에서 ClientEncryption을(를) 가져옵니다.

key_vault_database = "encryption"
key_vault_collection = "__keyVault"
key_vault_namespace = f"{key_vault_database}.{key_vault_collection}"
client = MongoClient(connection_string)
client_encryption = ClientEncryption(
kms_providers, # pass in the kms_providers variable from the previous step
key_vault_namespace,
client,
CodecOptions(uuid_representation=STANDARD),
)
data_key_id = client_encryption.create_data_key("local")
base_64_data_key_id = base64.b64encode(data_key_id)
print("DataKeyId [base64]: ", base_64_data_key_id)

위 코드의 출력은 다음과 유사해야 합니다.

DataKeyId [base64]: 3k13WkSZSLy7kwAAP4HDyQ==

참조: 코드 완성

데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

4
1

키 볼트 collection 네임스페이스로 encryption.__keyVault 을 지정합니다.

var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
keyVaultNamespace := "encryption.__keyVault"
String keyVaultNamespace = "encryption.__keyVault";
const keyVaultNamespace = "encryption.__keyVault";
key_vault_namespace = "encryption.__keyVault"
2

KMS 제공자를 지정하고 키를 인라인으로 지정합니다.

var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
var provider = "local";
var localMasterKeyPath = "master-key.txt";
string localMasterKeyBase64Read = File.ReadAllText(localMasterKeyPath);
var localMasterKeyBytes = Convert.FromBase64String(localMasterKeyBase64Read);
var localOptions = new Dictionary<string, object>
{
{ "key", localMasterKeyBytes }
};
kmsProviders.Add(provider, localOptions);
key, err := ioutil.ReadFile("master-key.txt")
if err != nil {
log.Fatalf("Could not read the key from master-key.txt: %v", err)
}
kmsProviders := map[string]map[string]interface{}{"local": {"key": key}}
String kmsProvider = "local";
String path = "master-key.txt";
byte[] localMasterKeyRead = new byte[96];
try (FileInputStream fis = new FileInputStream(path)) {
if (fis.read(localMasterKeyRead) < 96)
throw new Exception("Expected to read 96 bytes from file");
}
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put("key", localMasterKeyRead);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
kmsProviders.put("local", keyMap);
const fs = require("fs");
const provider = "local";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
path = "./master-key.txt"
with open(path, "rb") as f:
local_master_key = f.read()
kms_providers = {
"local": {
"key": local_master_key # local_master_key variable from the previous step
},
}
3

데이터 암호화 키 Base64 ID 추가하기

기본64 DEK ID를 포함하도록 다음 코드를 업데이트해야 합니다. 이 가이드의 데이터 암호화 키 생성 단계에서 이 값을 받았습니다.

var keyId = "<Your base64 DEK ID here>";
var schema = new BsonDocument
{
{ "bsonType", "object" },
{
"encryptMetadata",
new BsonDocument("keyId", new BsonArray(new[] { new BsonBinaryData(Convert.FromBase64String(keyId), BsonBinarySubType.UuidStandard) }))
},
{
"properties",
new BsonDocument
{
{
"ssn", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "int" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }
}
}
}
},
{
"bloodType", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "string" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" }
}
}
}
},
{
"medicalRecords", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "array" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" }
}
}
}
},
{
"insurance", new BsonDocument
{
{ "bsonType", "object" },
{
"properties", new BsonDocument
{
{
"policyNumber", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "int" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }
}
}
}
}
}
}
}
}
}
}
};
var schemaMap = new Dictionary<string, BsonDocument>();
schemaMap.Add(dbNamespace, schema);
dek_id := "<Your Base64 DEK ID>"
schema_template := `{
"bsonType": "object",
"encryptMetadata": {
"keyId": [
{
"$binary": {
"base64": "%s",
"subType": "04"
}
}
]
},
"properties": {
"insurance": {
"bsonType": "object",
"properties": {
"policyNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
}
},
"medicalRecords": {
"encrypt": {
"bsonType": "array",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
}
},
"bloodType": {
"encrypt": {
"bsonType": "string",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
}
},
"ssn": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
}
}`
schema := fmt.Sprintf(schema_template, dek_id)
var schemaDoc bson.Raw
if err := bson.UnmarshalExtJSON([]byte(schema), true, &schemaDoc); err != nil {
return fmt.Errorf("UnmarshalExtJSON error: %v", err)
}
schemaMap := map[string]interface{}{
dbName + "." + collName: schemaDoc,
}
String dekId = "<paste-base-64-encoded-data-encryption-key-id>>";
Document jsonSchema = new Document().append("bsonType", "object").append("encryptMetadata",
new Document().append("keyId", new ArrayList<>((Arrays.asList(new Document().append("$binary", new Document()
.append("base64", dekId)
.append("subType", "04")))))))
.append("properties", new Document()
.append("ssn", new Document().append("encrypt", new Document()
.append("bsonType", "int")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")))
.append("bloodType", new Document().append("encrypt", new Document()
.append("bsonType", "string")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random")))
.append("medicalRecords", new Document().append("encrypt", new Document()
.append("bsonType", "array")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random")))
.append("insurance", new Document()
.append("bsonType", "object")
.append("properties",
new Document().append("policyNumber", new Document().append("encrypt", new Document()
.append("bsonType", "int")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"))))));
HashMap<String, BsonDocument> schemaMap = new HashMap<String, BsonDocument>();
schemaMap.put("medicalRecords.patients", BsonDocument.parse(jsonSchema.toJson()));
dataKey = "<Your base64 DEK ID>";
const schema = {
bsonType: "object",
encryptMetadata: {
keyId: [new Binary(Buffer.from(dataKey, "base64"), 4)],
},
properties: {
insurance: {
bsonType: "object",
properties: {
policyNumber: {
encrypt: {
bsonType: "int",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
},
},
medicalRecords: {
encrypt: {
bsonType: "array",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
},
},
bloodType: {
encrypt: {
bsonType: "string",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
},
},
ssn: {
encrypt: {
bsonType: "int",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
},
};
var patientSchema = {};
patientSchema[namespace] = schema;
dek_id = b"<paste-base-64-encoded-data-encryption-key-id>"
json_schema = {
"bsonType": "object",
"encryptMetadata": {"keyId": [Binary(base64.b64decode(dek_id), UUID_SUBTYPE)]},
"properties": {
"insurance": {
"bsonType": "object",
"properties": {
"policyNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
}
}
},
},
"medicalRecords": {
"encrypt": {
"bsonType": "array",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
}
},
"bloodType": {
"encrypt": {
"bsonType": "string",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
}
},
"ssn": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
}
},
},
}
patient_schema = {"medicalRecords.patients": json_schema}
4
var mongoBinariesPath = "<Full path to your Automatic Encryption Shared Library>";
var extraOptions = new Dictionary<string, object>()
{
{ "cryptSharedLibPath", mongoBinariesPath },
};
extraOptions := map[string]interface{}{
"cryptSharedLibPath": "<Full path to your Automatic Encryption Shared Library>",
}
Map<String, Object> extraOptions = new HashMap<String, Object>();
extraOptions.put("cryptSharedLibPath", "<Full path to your Automatic Encryption Shared Library>"));
const extraOptions = {
cryptSharedLibPath: "<Full path to your Automatic Encryption Shared Library>",
};
extra_options = {
"cryptSharedLibPath": "<Full path to your Automatic Encryption Shared Library>"
}

참고

자동 암호화 옵션

자동 암호화 옵션은 자동 암호화 공유 라이브러리에 구성 정보를 제공하여 암호화된 필드에 액세스할 때 애플리케이션의 동작을 수정합니다.

자동 암호화 공유 라이브러리에 대해 자세히 알아보려면 CSFLE를 위한 자동 암호화 공유 라이브러리 페이지를 참조하세요.

5

다음 자동 암호화 설정을 사용하여 MongoDB 클라이언트 객체를 인스턴스화합니다.

var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
var autoEncryptionOptions = new AutoEncryptionOptions(
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
schemaMap: schemaMap,
extraOptions: extraOptions
);
clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
var secureClient = new MongoClient(clientSettings);
autoEncryptionOpts := options.AutoEncryption().
SetKmsProviders(kmsProviders).
SetKeyVaultNamespace(keyVaultNamespace).
SetSchemaMap(schemaMap).
SetExtraOptions(extraOptions)
secureClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri).SetAutoEncryptionOptions(autoEncryptionOpts))
if err != nil {
return fmt.Errorf("Connect error for encrypted client: %v", err)
}
defer func() {
_ = secureClient.Disconnect(context.TODO())
}()
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.schemaMap(schemaMap)
.extraOptions(extraOptions)
.build())
.build();
MongoClient mongoClientSecure = MongoClients.create(clientSettings);
const secureClient = new MongoClient(connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
autoEncryption: {
keyVaultNamespace,
kmsProviders,
schemaMap: patientSchema,
extraOptions: extraOptions,
},
});
fle_opts = AutoEncryptionOpts(
kms_providers, key_vault_namespace, schema_map=patient_schema, **extra_options
)
secureClient = MongoClient(connection_string, auto_encryption_opts=fle_opts)
5

CSFLE 지원 MongoClient 인스턴스를 사용하여 다음 코드 스니펫을 사용하여 암호화된 필드가 있는 문서를 medicalRecords.patients 네임스페이스에 삽입합니다.

var sampleDocFields = new BsonDocument
{
{ "name", "Jon Doe" },
{ "ssn", 145014000 },
{ "bloodType", "AB-" },
{
"medicalRecords", new BsonArray
{
new BsonDocument("weight", 180),
new BsonDocument("bloodPressure", "120/80")
}
},
{
"insurance", new BsonDocument
{
{ "policyNumber", 123142 },
{ "provider", "MaestCare" }
}
}
};
// Construct an auto-encrypting client
var secureCollection = secureClient.GetDatabase(db).GetCollection<BsonDocument>(coll);
// Insert a document into the collection
secureCollection.InsertOne(sampleDocFields);
test_patient := map[string]interface{}{
"name": "Jon Doe",
"ssn": 241014209,
"bloodType": "AB+",
"medicalRecords": []map[string]interface{}{{
"weight": 180,
"bloodPressure": "120/80",
}},
"insurance": map[string]interface{}{
"provider": "MaestCare",
"policyNumber": 123142,
},
}
if _, err := secureClient.Database(dbName).Collection(collName).InsertOne(context.TODO(), test_patient); err != nil {
return fmt.Errorf("InsertOne error: %v", err)
}

참고

원시 BSON 문서를 만드는 대신 bson 태그가 있는 구조체를 드라이버에 직접 전달하여 인코딩할 수 있습니다.

ArrayList<Document> medicalRecords = new ArrayList<>();
medicalRecords.add(new Document().append("weight", "180"));
medicalRecords.add(new Document().append("bloodPressure", "120/80"));
Document insurance = new Document()
.append("policyNumber", 123142)
.append("provider", "MaestCare");
Document patient = new Document()
.append("name", "Jon Doe")
.append("ssn", 241014209)
.append("bloodType", "AB+")
.append("medicalRecords", medicalRecords)
.append("insurance", insurance);
mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).insertOne(patient);
try {
const writeResult = await secureClient
.db(db)
.collection(coll)
.insertOne({
name: "Jon Doe",
ssn: 241014209,
bloodType: "AB+",
medicalRecords: [{ weight: 180, bloodPressure: "120/80" }],
insurance: {
policyNumber: 123142,
provider: "MaestCare",
},
});
} catch (writeError) {
console.error("writeError occurred:", writeError);
}
def insert_patient(
collection, name, ssn, blood_type, medical_records, policy_number, provider
):
insurance = {"policyNumber": policy_number, "provider": provider}
doc = {
"name": name,
"ssn": ssn,
"bloodType": blood_type,
"medicalRecords": medical_records,
"insurance": insurance,
}
collection.insert_one(doc)
medical_record = [{"weight": 180, "bloodPressure": "120/80"}]
insert_patient(
secureClient.medicalRecords.patients,
"Jon Doe",
241014209,
"AB+",
medical_record,
123142,
"MaestCare",
)

문서를 삽입하면 CSFLE 활성화 클라이언트는 다음과 유사하도록 문서의 필드를 암호화합니다.

{
"_id": { "$oid": "<_id of your document>" },
"name": "Jon Doe",
"ssn": {
"$binary": "<cipher-text>",
"$type": "6"
},
"bloodType": {
"$binary": "<cipher-text>",
"$type": "6"
},
"medicalRecords": {
"$binary": "<cipher-text>",
"$type": "6"
},
"insurance": {
"provider": "MaestCare",
"policyNumber": {
"$binary": "<cipher-text>",
"$type": "6"
}
}
}

참조: 코드 완성

암호화된 필드가 있는 문서를 삽입하기 위한 전체 코드를 보려면 Github 리포지토리 를 참조하세요.

암호화된 필드가 있는 문서를 삽입하기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

암호화된 필드가 있는 문서를 삽입하기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

암호화된 필드가 있는 문서를 삽입하기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

암호화된 필드가 있는 문서를 삽입하기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

6

이 가이드의 암호화된 필드가 있는 문서 삽입 단계에서 삽입한 암호화된 필드가 있는 문서를 검색합니다.

다음 코드 스니펫은 자동 CSFLE를 사용하도록 구성된 클라이언트와 자동 CSFLE를 사용하도록 구성되지 않은 클라이언트를 사용하여 문서에 대해 쿼리함으로써 CSFLE의 기능을 보여 줍니다.

Console.WriteLine("Finding a document with regular (non-encrypted) client.");
var filter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe");
var regularResult = regularCollection.Find(filter).Limit(1).ToList()[0];
Console.WriteLine($"\n{regularResult}\n");
Console.WriteLine("Finding a document with encrypted client, searching on an encrypted field");
var ssnFilter = Builders<BsonDocument>.Filter.Eq("ssn", 145014000);
var secureResult = secureCollection.Find(ssnFilter).Limit(1).First();
Console.WriteLine($"\n{secureResult}\n");
fmt.Println("Finding a document with regular (non-encrypted) client.")
var resultRegular bson.M
err = regularClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"name", "Jon Doe"}}).Decode(&resultRegular)
if err != nil {
panic(err)
}
outputRegular, err := json.MarshalIndent(resultRegular, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", outputRegular)
fmt.Println("Finding a document with encrypted client, searching on an encrypted field")
var resultSecure bson.M
err = secureClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"ssn", "241014209"}}).Decode(&resultSecure)
if err != nil {
panic(err)
}
outputSecure, err := json.MarshalIndent(resultSecure, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", outputSecure)
System.out.println("Finding a document with regular (non-encrypted) client.");
Document docRegular = mongoClientRegular.getDatabase(recordsDb).getCollection(recordsColl).find(eq("name", "Jon Doe")).first();
System.out.println(docRegular.toJson());
System.out.println("Finding a document with encrypted client, searching on an encrypted field");
Document docSecure = mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).find(eq("ssn", 241014209)).first();
System.out.println(docSecure.toJson());
console.log("Finding a document with regular (non-encrypted) client.");
console.log(
await regularClient.db(db).collection(coll).findOne({ name: /Jon/ })
);
console.log(
"Finding a document with encrypted client, searching on an encrypted field"
);
console.log(
await secureClient.db(db).collection(coll).findOne({ ssn: "241014209" })
);
print("Finding a document with regular (non-encrypted) client.")
result = regularClient.medicalRecords.patients.find_one({"name": "Jon Doe"})
pprint.pprint(result)
print("Finding a document with encrypted client, searching on an encrypted field")
pprint.pprint(secureClient.medicalRecords.patients.find_one({"ssn": 241014209}))

이전 코드 스니펫의 출력은 다음과 같아야 합니다.

Finding a document with regular (non-encrypted) client.
{
_id: new ObjectId("629a452e0861b3130887103a"),
name: 'Jon Doe',
ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
'key-id': 'demo-data-key',
medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
insurance: {
policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
provider: 'MaestCare'
}
}
Finding a document with encrypted client, searching on an encrypted field
{
_id: new ObjectId("629a452e0861b3130887103a"),
name: 'Jon Doe',
ssn: 241014209,
bloodType: 'AB+',
'key-id': 'demo-data-key',
medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
insurance: { policyNumber: 123142, provider: 'MaestCare' }
}

참조: 코드 완성

암호화된 필드가 있는 문서를 찾기 위한 전체 코드를 보려면 Github 리포지토리 를 참조하세요.

암호화된 필드가 있는 문서를 찾기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

암호화된 필드가 있는 문서를 찾기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

암호화된 필드가 있는 문서를 찾기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

암호화된 필드가 있는 문서를 찾기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.

원격 KMS를 사용하여 프로덕션에 즉시 사용 가능한 CSFLE에 대한 튜토리얼을 보려면 튜토리얼을 참조하세요 .

CSFLE 작동 방식을 알아보려면 기본 사항을 참조하세요.

이 가이드에 언급된 주제에 대해 자세히 알아보려면 다음 링크를 참조하세요:

돌아가기

설치