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

빠른 시작

이 페이지의 내용

  • 개요
  • 시작하기 전에
  • 절차
  • 애플리케이션 변수 할당
  • 암호화된 컬렉션 만들기
  • 암호화된 필드가 있는 문서 삽입하기
  • 암호화된 필드에 대한 쿼리
  • 자세히 알아보기

이 가이드에서는 문서 필드를 자동으로 암호화하고 해독하는 MongoDB Queryable Encryption 기능을 구현하는 애플리케이션을 구축하는 방법을 설명합니다.

오른쪽 드롭다운 메뉴에서 드라이버 언어를 선택하면 문서 필드를 자동으로 암호화하고 해독하는 애플리케이션을 만드는 방법을 알아볼 수 있습니다.

중요

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

이 튜토리얼의 지침에는 안전하지 않은 환경에 암호화 키를 저장하는 방법이 포함되어 있으므로 이 애플리케이션의 수정되지 않은 버전을 프로덕션 환경에서 사용해서는 안 됩니다. 프로덕션 환경에서 이 애플리케이션을 사용하면 암호화 키에 무단으로 액세스하거나 데이터 암호 해독에 필요한 키가 손실될 위험이 있습니다. 이 튜토리얼의 목적은 키 관리 시스템을 설정할 필요 없이 Queryable Encryption을 사용하는 방법을 설명하는 것입니다.

키 관리 시스템을 사용하여 프로덕션 환경에 암호화 키 를 안전하게 저장 수 있습니다. KMS 는 암호화 키를 안전하게 저장하고 관리하는 원격 서비스입니다. KMS 를 사용하는 Queryable Encryption 지원 애플리케이션 을 설정하다 하는 방법을 학습 보려면 Queryable Encryption 튜토리얼을 참조하세요.

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

참조: 전체 적용

이 샘플 애플리케이션의 전체 코드를 보려면 프로그래밍 언어에 해당하는 탭을 선택하고 제공된 링크를 따라가세요. 각 샘플 애플리케이션 리포지토리에는 환경을 설정하고 애플리케이션을 실행하는 방법을 배우는 데 사용할 수 있는 README.md 파일이 포함되어 있습니다.

mongosh 애플리케이션 완성

1

이 튜토리얼의 코드 샘플에서는 다음 변수를 사용하여 Queryable Encryption 워크플로를 수행합니다.

  • kmsProviderName - 고객 마스터 키를 저장하는 데 사용하는 KMS입니다. 이 튜토리얼에서는 이 변수를 "local" 로 설정합니다.

  • uri - MongoDB 배포 연결 URI입니다. MONGODB_URI 환경 변수에 연결 URI를 설정하거나 값을 직접 바꿉니다.

  • keyVaultDatabaseName - 데이터 암호화 키(DEK)가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "encryption" 으로 설정합니다.

  • keyVaultCollectionName - DEK가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "__keyVault" 으로 설정하면 사용자 컬렉션으로 잘못 인식되는 것을 방지할 수 있습니다.

  • keyVaultNamespace - DEK가 저장될 MongoDB의 네임스페이스입니다. 이 변수를 마침표로 구분된 keyVaultDatabaseNamekeyVaultCollectionName 변수의 값으로 설정합니다.

  • encryptedDatabaseName - 암호화된 데이터가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "medicalRecords"(으)로 설정합니다.

  • encryptionCollectionName - 암호화된 데이터가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "patients" 으로 설정합니다.

다음 코드를 사용하여 이러한 변수를 선언할 수 있습니다.

// KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
const kmsProviderName = "<Your KMS Provider Name>";
const uri = process.env.MONGODB_URI; // Your connection URI
const keyVaultDatabaseName = "encryption";
const keyVaultCollectionName = "__keyVault";
const keyVaultNamespace = `${keyVaultDatabaseName}.${keyVaultCollectionName}`;
const encryptedDatabaseName = "medicalRecords";
const encryptedCollectionName = "patients";
  • kmsProviderName - 고객 마스터 키를 저장하는 데 사용하는 KMS입니다. 이 튜토리얼에서는 이 값을 "local" 로 설정합니다.

  • keyVaultDatabaseName - 데이터 암호화 키(DEK)가 저장될 MongoDB의 데이터베이스입니다. keyVaultDatabaseName 의 값을 "encryption" 로 설정합니다.

  • keyVaultCollectionName - DEK가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "__keyVault" 으로 설정하면 사용자 컬렉션으로 잘못 인식되는 것을 방지할 수 있습니다.

  • keyVaultNamespace - DEK가 저장될 MongoDB의 네임스페이스입니다. keyVaultDatabaseNamekeyVaultCollectionName 변수의 값이 마침표로 구분된 이름을 가진 새 CollectionNamespace 객체로 keyVaultNamespace 를 설정합니다.

  • encryptionDatabaseName - 암호화된 데이터가 저장될 MongoDB의 데이터베이스입니다. encryptedDatabaseName 의 값을 "medicalRecords" 로 설정합니다.

  • encryptedCollectionName - 암호화된 데이터가 저장될 MongoDB의 collection입니다. encryptedCollectionName 의 값을 "patients" 로 설정합니다.

  • uri - MongoDB 배포 연결 URI입니다. appsettings.json 파일에서 연결 URI를 설정하거나 값을 직접 바꿉니다.

다음 코드를 사용하여 이러한 변수를 선언할 수 있습니다.

// KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
const string kmsProviderName = "<your KMS provider name>";
const string keyVaultDatabaseName = "encryption";
const string keyVaultCollectionName = "__keyVault";
var keyVaultNamespace =
CollectionNamespace.FromFullName($"{keyVaultDatabaseName}.{keyVaultCollectionName}");
const string encryptedDatabaseName = "medicalRecords";
const string encryptedCollectionName = "patients";
var appSettings = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var uri = appSettings["MongoDbUri"];
  • kmsProviderName - 고객 마스터 키를 저장하는 데 사용하는 KMS입니다. 이 튜토리얼에서는 이 변수를 "local" 로 설정합니다.

  • uri - MongoDB 배포 연결 URI입니다. MONGODB_URI 환경 변수에 연결 URI를 설정하거나 값을 직접 바꿉니다.

  • keyVaultDatabaseName - 데이터 암호화 키(DEK)가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "encryption" 으로 설정합니다.

  • keyVaultCollectionName - DEK가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "__keyVault" 으로 설정하면 사용자 컬렉션으로 잘못 인식되는 것을 방지할 수 있습니다.

  • keyVaultNamespace - DEK가 저장될 MongoDB의 네임스페이스입니다. 이 변수를 마침표로 구분된 keyVaultDatabaseNamekeyVaultCollectionName 변수의 값으로 설정합니다.

  • encryptedDatabaseName - 암호화된 데이터가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "medicalRecords"(으)로 설정합니다.

  • encryptionCollectionName - 암호화된 데이터가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "patients" 으로 설정합니다.

다음 코드를 사용하여 이러한 변수를 선언할 수 있습니다.

// KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
kmsProviderName := "<KMS provider name>"
uri := os.Getenv("MONGODB_URI") // Your connection URI
keyVaultDatabaseName := "encryption"
keyVaultCollectionName := "__keyVault"
keyVaultNamespace := keyVaultDatabaseName + "." + keyVaultCollectionName
encryptedDatabaseName := "medicalRecords"
encryptedCollectionName := "patients"
  • kmsProviderName - 고객 마스터 키를 저장하는 데 사용하는 KMS입니다. 이 튜토리얼에서는 이 변수를 "local" 로 설정합니다.

  • uri - MongoDB 배포 연결 URI입니다. MONGODB_URI 환경 변수에 연결 URI를 설정하거나 값을 직접 바꿉니다.

  • keyVaultDatabaseName - 데이터 암호화 키(DEK)가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "encryption" 으로 설정합니다.

  • keyVaultCollectionName - DEK가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "__keyVault" 으로 설정하면 사용자 컬렉션으로 잘못 인식되는 것을 방지할 수 있습니다.

  • keyVaultNamespace - DEK가 저장될 MongoDB의 네임스페이스입니다. 이 변수를 마침표로 구분된 keyVaultDatabaseNamekeyVaultCollectionName 변수의 값으로 설정합니다.

  • encryptedDatabaseName - 암호화된 데이터가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "medicalRecords"(으)로 설정합니다.

  • encryptionCollectionName - 암호화된 데이터가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "patients" 으로 설정합니다.

다음 코드를 사용하여 이러한 변수를 선언할 수 있습니다.

// KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
String kmsProviderName = "<KMS provider name>";
String uri = QueryableEncryptionHelpers.getEnv("MONGODB_URI"); // Your connection URI
String keyVaultDatabaseName = "encryption";
String keyVaultCollectionName = "__keyVault";
String keyVaultNamespace = keyVaultDatabaseName + "." + keyVaultCollectionName;
String encryptedDatabaseName = "medicalRecords";
String encryptedCollectionName = "patients";
  • kmsProviderName - 고객 마스터 키를 저장하는 데 사용하는 KMS입니다. 이 튜토리얼에서는 이 변수를 "local" 로 설정합니다.

  • uri - MongoDB 배포 연결 URI입니다. MONGODB_URI 환경 변수에 연결 URI를 설정하거나 값을 직접 바꿉니다.

  • keyVaultDatabaseName - 데이터 암호화 키(DEK)가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "encryption" 으로 설정합니다.

  • keyVaultCollectionName - DEK가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "__keyVault" 으로 설정하면 사용자 컬렉션으로 잘못 인식되는 것을 방지할 수 있습니다.

  • keyVaultNamespace - DEK가 저장될 MongoDB의 네임스페이스입니다. 이 변수를 마침표로 구분된 keyVaultDatabaseNamekeyVaultCollectionName 변수의 값으로 설정합니다.

  • encryptedDatabaseName - 암호화된 데이터가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "medicalRecords"(으)로 설정합니다.

  • encryptionCollectionName - 암호화된 데이터가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "patients" 으로 설정합니다.

다음 코드를 사용하여 이러한 변수를 선언할 수 있습니다.

// KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
const kmsProviderName = "<Your KMS Provider Name>";
const uri = process.env.MONGODB_URI; // Your connection URI
const keyVaultDatabaseName = "encryption";
const keyVaultCollectionName = "__keyVault";
const keyVaultNamespace = `${keyVaultDatabaseName}.${keyVaultCollectionName}`;
const encryptedDatabaseName = "medicalRecords";
const encryptedCollectionName = "patients";
  • kms_provider_name - 고객 마스터 키를 저장하는 데 사용하는 KMS입니다. 이 튜토리얼에서는 이 변수를 "local" 로 설정합니다.

  • uri - MongoDB 배포 연결 URI입니다. MONGODB_URI 환경 변수에 연결 URI를 설정하거나 값을 직접 바꿉니다.

  • key_vault_database_name - 데이터 암호화 키(DEK)가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "encryption" 으로 설정합니다.

  • key_vault_collection_name - DEK가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "__keyVault" 으로 설정하면 사용자 컬렉션으로 잘못 인식되는 것을 방지할 수 있습니다.

  • key_vault_namespace - DEK가 저장될 MongoDB의 네임스페이스입니다. 이 변수를 마침표로 구분된 key_vault_database_namekey_vault_collection_name 변수의 값으로 설정합니다.

  • encryption_database_name - 암호화된 데이터가 저장될 MongoDB의 데이터베이스입니다. 이 변수를 "medicalRecords" 으로 설정합니다.

  • encryption_collection_name - 암호화된 데이터가 저장될 MongoDB의 컬렉션입니다. 이 변수를 "patients" 으로 설정합니다.

다음 코드를 사용하여 이러한 변수를 선언할 수 있습니다.

# KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
kms_provider_name = "<KMS provider name>"
uri = os.environ['MONGODB_URI'] # Your connection URI
key_vault_database_name = "encryption"
key_vault_collection_name = "__keyVault"
key_vault_namespace = f"{key_vault_database_name}.{key_vault_collection_name}"
encrypted_database_name = "medicalRecords"
encrypted_collection_name = "patients"

중요

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

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

  • encryption.__keyVault

  • medicalRecords database

환경 변수

이 튜토리얼의 샘플 코드는 설정해야 하는 환경 변수를 참조합니다. 또는 코드에서 직접 값을 바꿀 수도 있습니다.

이러한 환경 변수를 설정하는 방법을 알아보려면 README.md 를 참조하세요. 파일은 GitHub의 샘플 애플리케이션에 포함되어 있습니다.

환경 변수

이 튜토리얼의 샘플 코드는 설정해야 하는 환경 변수를 참조합니다. 또는 코드에서 직접 값을 바꿀 수도 있습니다.

이러한 환경 변수를 설정하는 방법을 알아보려면 README.md 를 참조하세요. 파일은 GitHub의 샘플 애플리케이션에 포함되어 있습니다.

환경 변수

이 튜토리얼의 샘플 코드는 설정해야 하는 환경 변수를 참조합니다. 또는 코드에서 직접 값을 바꿀 수도 있습니다.

이러한 환경 변수를 설정하는 방법을 알아보려면 README.md 를 참조하세요. 파일은 GitHub의 샘플 애플리케이션에 포함되어 있습니다.

환경 변수

이 튜토리얼의 샘플 코드는 설정해야 하는 환경 변수를 참조합니다. 또는 코드에서 직접 값을 바꿀 수도 있습니다.

이러한 환경 변수를 설정하는 방법을 알아보려면 README.md 를 참조하세요. 파일은 GitHub의 샘플 애플리케이션에 포함되어 있습니다.

환경 변수

이 튜토리얼의 샘플 코드는 설정해야 하는 환경 변수를 참조합니다. 또는 코드에서 직접 값을 바꿀 수도 있습니다.

이러한 환경 변수를 설정하는 방법을 알아보려면 README.md 를 참조하세요. 파일은 GitHub의 샘플 애플리케이션에 포함되어 있습니다.

환경 변수

이 튜토리얼의 샘플 코드는 설정해야 하는 환경 변수를 참조합니다. 또는 코드에서 직접 값을 바꿀 수도 있습니다.

이러한 환경 변수를 설정하는 방법을 알아보려면 README.md 를 참조하세요. 파일은 GitHub의 샘플 애플리케이션에 포함되어 있습니다.

2
1

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

96바이트 고객 마스터 키를 생성하여 파일 시스템에 customer-master-key.txt 파일로 저장합니다.

customerMasterKeyPath = "customer-master-key.txt";
if (!fs.existsSync(customerMasterKeyPath)) {
fs.writeFileSync(customerMasterKeyPath, crypto.randomBytes(96));
}
using var randomNumberGenerator = RandomNumberGenerator.Create();
try
{
var bytes = new byte[96];
randomNumberGenerator.GetBytes(bytes);
var localCustomerMasterKeyBase64 = Convert.ToBase64String(bytes);
File.WriteAllText("customer-master-key.txt", localCustomerMasterKeyBase64);
}
catch (Exception e)
{
throw new Exception("Unable to write Customer Master Key file due to the following error: " + e.Message);
}
key := make([]byte, 96)
if _, err := rand.Read(key); err != nil {
panic(fmt.Sprintf("Unable to create a random 96 byte data key: %v\n", err))
}
if err := os.WriteFile("customer-master-key.txt", key, 0644); err != nil {
panic(fmt.Sprintf("Unable to write key to file: %v\n", err))
}
byte[] localCustomerMasterKey = new byte[96];
new SecureRandom().nextBytes(localCustomerMasterKey);
try (FileOutputStream stream = new FileOutputStream("customer-master-key.txt")) {
stream.write(localCustomerMasterKey);
// ...
if (!existsSync("./customer-master-key.txt")) {
try {
writeFileSync("customer-master-key.txt", randomBytes(96));
} catch (err) {
throw new Error(
`Unable to write Customer Master Key to file due to the following error: ${err}`
);
}
}
path = "customer-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 파일에 저장합니다.

2

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

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

// WARNING: Do not use a local key file in a production application
const localMasterKey = fs.readFileSync("./customer-master-key.txt");
if (localMasterKey.length !== 96) {
throw new Error(
"Expected the customer master key file to be 96 bytes."
);
}
kmsProviderCredentials = {
local: {
key: localMasterKey,
},
};
// WARNING: Do not use a local key file in a production application
var kmsProviderCredentials = new Dictionary<string, IReadOnlyDictionary<string, object>>();
try
{
var localCustomerMasterKeyBase64 = File.ReadAllText("customer-master-key.txt");
var localCustomerMasterKeyBytes = Convert.FromBase64String(localCustomerMasterKeyBase64);
if (localCustomerMasterKeyBytes.Length != 96)
{
throw new Exception("Expected the customer master key file to be 96 bytes.");
}
var localOptions = new Dictionary<string, object>
{
{ "key", localCustomerMasterKeyBytes }
};
kmsProviderCredentials.Add("local", localOptions);
}
key, err := os.ReadFile("customer-master-key.txt")
if err != nil {
panic(fmt.Sprintf("Could not read the Customer Master Key: %v", err))
}
if len(key) != 96 {
panic(fmt.Sprintf("Expected the customer master key file to be 96 bytes."))
}
kmsProviderCredentials := map[string]map[string]interface{}{"local": {"key": key}}
byte[] localCustomerMasterKey = new byte[96];
try (FileInputStream fis = new FileInputStream("customer-master-key.txt")) {
if (fis.read(localCustomerMasterKey) != 96)
throw new Exception("Expected the customer master key file to be 96 bytes.");
} catch (Exception e) {
throw new Exception("Unable to read the Customer Master Key due to the following error: " + e.getMessage());
}
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put("key", localCustomerMasterKey);
Map<String, Map<String, Object>> kmsProviderCredentials = new HashMap<String, Map<String, Object>>();
kmsProviderCredentials.put("local", keyMap);
// WARNING: Do not use a local key file in a production application
const localMasterKey = readFileSync("./customer-master-key.txt");
if (localMasterKey.length !== 96) {
throw new Error(
"Expected the customer master key file to be 96 bytes."
);
}
kmsProviders = {
local: {
key: localMasterKey,
},
};
path = "./customer-master-key.txt"
with open(path, "rb") as f:
local_master_key = f.read()
if len(local_master_key) != 96:
raise Exception("Expected the customer master key file to be 96 bytes.")
kms_provider_credentials = {
"local": {
"key": local_master_key
},
}
3

다음 옵션을 포함하는 autoEncryptionOptions 객체를 만듭니다.

  • 키 볼트 컬렉션의 네임스페이스

  • 이전 단계에서 정의된 kmsProviderCredentials 객체

const autoEncryptionOptions = {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviderCredentials,
};

다음 옵션을 포함하는 AutoEncryptionOptions 객체를 만듭니다.

  • 키 볼트 컬렉션의 네임스페이스

  • 이전 단계에서 정의된 kmsProviderCredentials 객체

  • 자동 암호화 공유 라이브러리의 경로가 포함된 extraOptions 객체

var extraOptions = new Dictionary<string, object>
{
{ "cryptSharedLibPath", _appSettings["CryptSharedLibPath"] } // Path to your Automatic Encryption Shared Library
};
var autoEncryptionOptions = new AutoEncryptionOptions(
keyVaultNamespace,
kmsProviderCredentials,
extraOptions: extraOptions);

다음 옵션을 포함하는 AutoEncryption 객체를 만듭니다.

  • 키 볼트 컬렉션의 네임스페이스

  • 이전 단계에서 정의된 kmsProviderCredentials 객체

  • 자동 암호화 공유 라이브러리의 경로가 포함된 cryptSharedLibraryPath 객체

cryptSharedLibraryPath := map[string]interface{}{
"cryptSharedLibPath": os.Getenv("SHARED_LIB_PATH"), // Path to your Automatic Encryption Shared Library
}
autoEncryptionOptions := options.AutoEncryption().
SetKeyVaultNamespace(keyVaultNamespace).
SetKmsProviders(kmsProviderCredentials).
SetExtraOptions(cryptSharedLibraryPath)

다음 옵션을 포함하는 AutoEncryptionSettings 객체를 만듭니다.

  • 키 볼트 컬렉션의 네임스페이스

  • 이전 단계에서 정의된 kmsProviderCredentials 객체

  • 자동 암호화 공유 라이브러리의 경로가 포함된 extraOptions 객체

Map<String, Object> extraOptions = new HashMap<String, Object>();
extraOptions.put("cryptSharedLibPath", getEnv("SHARED_LIB_PATH")); // Path to your Automatic Encryption Shared Library
AutoEncryptionSettings autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviderCredentials)
.extraOptions(extraOptions)
.build();

다음 옵션을 포함하는 autoEncryptionOptions 객체를 만듭니다.

  • 키 볼트 컬렉션의 네임스페이스

  • 이전 단계에서 정의된 kmsProviders 객체

  • 자동 암호화 공유 라이브러리의 경로가 포함된 sharedLibraryPathOptions 객체

const extraOptions = {
cryptSharedLibPath: process.env.SHARED_LIB_PATH, // Path to your Automatic Encryption Shared Library
};
const autoEncryptionOptions = {
keyVaultNamespace,
kmsProviders,
extraOptions,
};

다음 옵션을 포함하는 AutoEncryptionOpts 객체를 만듭니다.

  • 이전 단계에서 정의된 kms_provider_credentials 객체

  • 키 볼트 컬렉션의 네임스페이스

  • 자동 암호화 공유 라이브러리의 경로

auto_encryption_options = AutoEncryptionOpts(
kms_provider_credentials,
key_vault_namespace,
crypt_shared_lib_path=os.environ['SHARED_LIB_PATH'] # Path to your Automatic Encryption Shared Library>
)

참고

자동 암호화 옵션

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

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

4

컬렉션의 데이터를 암호화 및 암호 해독하는 데 사용되는 클라이언트를 만들려면 연결 URI 및 자동 암호화 옵션을 사용하여 새 MongoClient를 인스턴스화합니다.

const encryptedClient = Mongo(uri, autoEncryptionOpts);
var clientSettings = MongoClientSettings.FromConnectionString(uri);
clientSettings.AutoEncryptionOptions = qeHelpers.GetAutoEncryptionOptions(
keyVaultNamespace,
kmsProviderCredentials);
var encryptedClient = new MongoClient(clientSettings);
encryptedClient, err := mongo.Connect(
context.TODO(),
options.Client().ApplyURI(uri).SetAutoEncryptionOptions(autoEncryptionOptions),
)
if err != nil {
panic(fmt.Sprintf("Unable to connect to MongoDB: %v\n", err))
}
defer func() {
_ = encryptedClient.Disconnect(context.TODO())
}()
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(uri))
.autoEncryptionSettings(autoEncryptionSettings)
.build();
try (MongoClient encryptedClient = MongoClients.create(clientSettings)) {
const encryptedClient = new MongoClient(uri, {
autoEncryption: autoEncryptionOptions,
});
encrypted_client = MongoClient(
uri, auto_encryption_opts=auto_encryption_options)
5

필드를 암호화하려면 암호화 스키마에 추가합니다. 필드에서 쿼리를 활성화하려면 'queries' 속성을 추가합니다. 다음과 같이 암호화 스키마를 생성합니다.

const encryptedFieldsMap = {
encryptedFields: {
fields: [
{
path: "patientRecord.ssn",
bsonType: "string",
queries: { queryType: "equality" },
},
{
path: "patientRecord.billing",
bsonType: "object",
},
],
},
};
var encryptedFields = new BsonDocument
{
{
"fields", new BsonArray
{
new BsonDocument
{
{ "keyId", BsonNull.Value },
{ "path", "patientRecord.ssn" },
{ "bsonType", "string" },
{ "queries", new BsonDocument("queryType", "equality") }
},
new BsonDocument
{
{ "keyId", BsonNull.Value },
{ "path", "patientRecord.billing" },
{ "bsonType", "object" }
}
}
}
};
encryptedFieldsMap := bson.M{
"fields": []bson.M{
bson.M{
"keyId": nil,
"path": "patientRecord.ssn",
"bsonType": "string",
"queries": []bson.M{
{
"queryType": "equality",
},
},
},
bson.M{
"keyId": nil,
"path": "patientRecord.billing",
"bsonType": "object",
},
},
}
BsonDocument encryptedFieldsMap = new BsonDocument().append("fields",
new BsonArray(Arrays.asList(
new BsonDocument()
.append("keyId", new BsonNull())
.append("path", new BsonString("patientRecord.ssn"))
.append("bsonType", new BsonString("string"))
.append("queries", new BsonDocument()
.append("queryType", new BsonString("equality"))),
new BsonDocument()
.append("keyId", new BsonNull())
.append("path", new BsonString("patientRecord.billing"))
.append("bsonType", new BsonString("object")))));
const encryptedFieldsMap = {
encryptedFields: {
fields: [
{
path: "patientRecord.ssn",
bsonType: "string",
queries: { queryType: "equality" },
},
{
path: "patientRecord.billing",
bsonType: "object",
},
],
},
};
encrypted_fields_map = {
"fields": [
{
"path": "patientRecord.ssn",
"bsonType": "string",
"queries": [{"queryType": "equality"}]
},
{
"path": "patientRecord.billing",
"bsonType": "object",
}
]
}

참고

이전 코드 샘플에서는 "ssn" 및 "billing" 필드가 모두 암호화되어 있지만 "ssn" 필드만 쿼리할 수 있습니다.

6

ClientEncryption을 인스턴스화하여 암호화 헬퍼 메서드용 API에 액세스합니다.

const clientEncryption = encryptedClient.getClientEncryption();
var clientEncryptionOptions = new ClientEncryptionOptions(
keyVaultClient: keyVaultClient,
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviderCredentials
);
var clientEncryption = new ClientEncryption(clientEncryptionOptions);
opts := options.ClientEncryption().
SetKeyVaultNamespace(keyVaultNamespace).
SetKmsProviders(kmsProviderCredentials)
clientEncryption, err := mongo.NewClientEncryption(encryptedClient, opts)
if err != nil {
panic(fmt.Sprintf("Unable to create a ClientEncryption instance due to the following error: %s\n", err))
}
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(uri))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviderCredentials)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
const clientEncryption = new ClientEncryption(
encryptedClient,
autoEncryptionOptions
);
client_encryption = ClientEncryption(
kms_providers=kms_provider_credentials,
key_vault_namespace=key_vault_namespace,
key_vault_client=encrypted_client,
codec_options=CodecOptions(uuid_representation=STANDARD)
)

로컬 고객 마스터 키를 사용하기 때문에 고객 마스터 키 자격 증명을 제공할 필요가 없습니다. 암호화된 컬렉션을 생성할 때 자격 증명 대신 사용할 빈 객체가 포함된 변수를 생성합니다.

customerMasterKeyCredentials = {};
var customerMasterKeyCredentials = new BsonDocument();
cmkCredentials := map[string]string{}
BsonDocument customerMasterKeyCredentials = new BsonDocument();
customerMasterKeyCredentials = {};
customer_master_key_credentials = {}

ClientEncryption 클래스를 통해 액세스하는 암호화 헬퍼 메서드를 사용하여 암호화된 컬렉션을 만듭니다. 이 메서드는 암호화된 필드에 대한 데이터 암호화 키를 자동으로 생성하고 암호화된 컬렉션을 생성합니다.

await clientEncryption.createEncryptedCollection(
encryptedDatabaseName,
encryptedCollectionName,
{
provider: kmsProviderName,
createCollectionOptions: encryptedFieldsMap,
masterKey: customerMasterKeyCredentials,
}
);

이 튜토리얼의 C# 버전에서는 별도의 클래스를 데이터 모델로 사용하여 문서 구조를 나타냅니다. 프로젝트에 다음 Patient , PatientRecordPatientBilling 클래스를 추가합니다.

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
[BsonIgnoreExtraElements]
public class Patient
{
public ObjectId Id { get; set; }
public string PatientName { get; set; }
public PatientRecord PatientRecord { get; set; }
}
public class PatientRecord
{
public string Ssn { get; set; }
public PatientBilling Billing { get; set; }
public int BillAmount { get; set; }
}
public class PatientBilling
{
public string CardType { get; set; }
public long CardNumber { get; set; }
}

이러한 클래스를 추가한 후 ClientEncryption 클래스를 통해 액세스하는 암호화 헬퍼 메서드를 사용하여 암호화된 collection을 만듭니다. 이 메서드는 암호화된 필드에 대한 데이터 암호화 키를 자동으로 생성하고 암호화된 collection을 생성합니다.

var createCollectionOptions = new CreateCollectionOptions<Patient>
{
EncryptedFields = encryptedFields
};
clientEncryption.CreateEncryptedCollection(patientDatabase,
encryptedCollectionName,
createCollectionOptions,
kmsProviderName,
customerMasterKeyCredentials);

데이터베이스 대 데이터베이스 이름

암호화된 컬렉션을 생성하는 방법에는 데이터베이스 이름이 아닌 데이터베이스 객체에 대한 참조가 필요합니다. 클라이언트 객체의 메서드를 사용하여 이 참조를 얻을 수 있습니다.

이 튜토리얼의 Go 버전에서는 데이터 모델을 사용하여 문서 구조를 나타냅니다. 프로젝트에 다음 구조체를 추가하여 컬렉션의 데이터를 나타냅니다.

type PatientDocument struct {
PatientName string `bson:"patientName"`
PatientID int32 `bson:"patientId"`
PatientRecord PatientRecord `bson:"patientRecord"`
}
type PatientRecord struct {
SSN string `bson:"ssn"`
Billing PaymentInfo `bson:"billing"`
BillAmount int `bson:"billAmount"`
}
type PaymentInfo struct {
Type string `bson:"type"`
Number string `bson:"number"`
}

이러한 클래스를 추가한 후 ClientEncryption 클래스를 통해 액세스하는 암호화 헬퍼 메서드를 사용하여 암호화된 collection을 만듭니다. 이 메서드는 암호화된 필드에 대한 데이터 암호화 키를 자동으로 생성하고 암호화된 collection을 생성합니다.

createCollectionOptions := options.CreateCollection().SetEncryptedFields(encryptedFieldsMap)
_, _, err =
clientEncryption.CreateEncryptedCollection(
context.TODO(),
encryptedClient.Database(encryptedDatabaseName),
encryptedCollectionName,
createCollectionOptions,
kmsProviderName,
customerMasterKey,
)

데이터베이스 대 데이터베이스 이름

암호화된 컬렉션을 생성하는 방법에는 데이터베이스 이름이 아닌 데이터베이스 객체에 대한 참조가 필요합니다. 클라이언트 객체의 메서드를 사용하여 이 참조를 얻을 수 있습니다.

ClientEncryption 클래스를 통해 액세스하는 암호화 헬퍼 메서드를 사용하여 암호화된 컬렉션을 만듭니다. 이 메서드는 암호화된 필드에 대한 데이터 암호화 키를 자동으로 생성하고 암호화된 컬렉션을 생성합니다.

CreateCollectionOptions createCollectionOptions = new CreateCollectionOptions().encryptedFields(encryptedFieldsMap);
CreateEncryptedCollectionParams encryptedCollectionParams = new CreateEncryptedCollectionParams(kmsProviderName);
encryptedCollectionParams.masterKey(customerMasterKeyCredentials);
try {
clientEncryption.createEncryptedCollection(
encryptedClient.getDatabase(encryptedDatabaseName),
encryptedCollectionName,
createCollectionOptions,
encryptedCollectionParams);
}

데이터베이스 대 데이터베이스 이름

암호화된 컬렉션을 생성하는 방법에는 데이터베이스 이름이 아닌 데이터베이스 객체에 대한 참조가 필요합니다. 클라이언트 객체의 메서드를 사용하여 이 참조를 얻을 수 있습니다.

ClientEncryption 클래스를 통해 액세스하는 암호화 헬퍼 메서드를 사용하여 암호화된 컬렉션을 만듭니다. 이 메서드는 암호화된 필드에 대한 데이터 암호화 키를 자동으로 생성하고 암호화된 컬렉션을 생성합니다.

참고

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

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

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

await clientEncryption.createEncryptedCollection(
encryptedDatabase,
encryptedCollectionName,
{
provider: kmsProviderName,
createCollectionOptions: encryptedFieldsMap,
masterKey: customerMasterKeyCredentials,
}
);

데이터베이스 대 데이터베이스 이름

암호화된 컬렉션을 생성하는 방법에는 데이터베이스 이름이 아닌 데이터베이스 객체에 대한 참조가 필요합니다. 클라이언트 객체의 메서드를 사용하여 이 참조를 얻을 수 있습니다.

ClientEncryption 클래스를 통해 액세스하는 암호화 헬퍼 메서드를 사용하여 암호화된 컬렉션을 만듭니다. 이 메서드는 암호화된 필드에 대한 데이터 암호화 키를 자동으로 생성하고 암호화된 컬렉션을 생성합니다.

client_encryption.create_encrypted_collection(
encrypted_client[encrypted_database_name],
encrypted_collection_name,
encrypted_fields_map,
kms_provider_name,
customer_master_key_credentials,
)

데이터베이스 대 데이터베이스 이름

암호화된 컬렉션을 생성하는 방법에는 데이터베이스 이름이 아닌 데이터베이스 객체에 대한 참조가 필요합니다. 클라이언트 객체의 메서드를 사용하여 이 참조를 얻을 수 있습니다.

3

환자의 개인 정보를 설명하는 샘플 문서를 만듭니다. 다음 예시와 같이 암호화된 클라이언트를 사용하여 patients 컬렉션에 삽입합니다.

const patientDocument = {
patientName: "Jon Doe",
patientId: 12345678,
patientRecord: {
ssn: "987-65-4320",
billing: {
type: "Visa",
number: "4111111111111111",
},
billAmount: 1500,
},
};
const encryptedCollection = encryptedClient
.getDB(encryptedDatabaseName)
.getCollection(encryptedCollectionName);
const insertResult = await encryptedCollection.insertOne(patientDocument);

환자의 개인 정보를 설명하는 샘플 문서를 만듭니다. 다음 예시와 같이 암호화된 클라이언트를 사용하여 patients 컬렉션에 삽입합니다.

var patient = new Patient
{
PatientName = "Jon Doe",
Id = new ObjectId(),
PatientRecord = new PatientRecord
{
Ssn = "987-65-4320",
Billing = new PatientBilling
{
CardType = "Visa",
CardNumber = 4111111111111111,
},
BillAmount = 1500
}
};
var encryptedCollection = encryptedClient.GetDatabase(encryptedDatabaseName).
GetCollection<Patient>(encryptedCollectionName);
encryptedCollection.InsertOne(patient);

환자의 개인 정보를 설명하는 샘플 문서를 만듭니다. 다음 예시와 같이 암호화된 클라이언트를 사용하여 patients 컬렉션에 삽입합니다.

patientDocument := &PatientDocument{
PatientName: "Jon Doe",
PatientID: 12345678,
PatientRecord: PatientRecord{
SSN: "987-65-4320",
Billing: PaymentInfo{
Type: "Visa",
Number: "4111111111111111",
},
BillAmount: 1500,
},
}
coll := encryptedClient.Database(encryptedDatabaseName).Collection(encryptedCollectionName)
_, err = coll.InsertOne(context.TODO(), patientDocument)
if err != nil {
panic(fmt.Sprintf("Unable to insert the patientDocument: %s", err))
}

이 튜토리얼에서는 POJO를 데이터 모델로 사용하여 문서 구조를 나타냅니다. POJO를 사용하도록 애플리케이션을 설정하려면 다음 코드를 추가하세요.

CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));

Java POJO에 대해 자세히 알아보려면 Plain Old Java Object 위키백과 문서를 참조하세요.

이 튜토리얼에서는 다음 POJO를 사용합니다.

  • Patient

  • PatientRecord

  • PatientBilling

이러한 클래스 는 전체 Java 애플리케이션의 모델 패키지에서 확인할 수 있습니다.

이러한 POJO 클래스를 애플리케이션에 추가합니다. 그런 다음 환자의 개인 정보를 설명하는 Patient 인스턴스를 만듭니다. 다음 예와 같이 암호화된 클라이언트를 사용하여 patients 컬렉션에 삽입합니다.

MongoDatabase encryptedDb = encryptedClient.getDatabase(encryptedDatabaseName).withCodecRegistry(pojoCodecRegistry);
MongoCollection<Patient> collection = encryptedDb.getCollection(encryptedCollectionName, Patient.class);
PatientBilling patientBilling = new PatientBilling("Visa", "4111111111111111");
PatientRecord patientRecord = new PatientRecord("987-65-4320", patientBilling, 1500);
Patient patientDocument = new Patient("Jon Doe", patientRecord);
InsertOneResult result = collection.insertOne(patientDocument);

환자의 개인 정보를 설명하는 샘플 문서를 만듭니다. 다음 예시와 같이 암호화된 클라이언트를 사용하여 patients 컬렉션에 삽입합니다.

const patientDocument = {
patientName: "Jon Doe",
patientId: 12345678,
patientRecord: {
ssn: "987-65-4320",
billing: {
type: "Visa",
number: "4111111111111111",
},
billAmount: 1500,
},
};
const encryptedCollection = encryptedClient
.db(encryptedDatabaseName)
.collection(encryptedCollectionName);
const result = await encryptedCollection.insertOne(patientDocument);

환자의 개인 정보를 설명하는 샘플 문서를 만듭니다. 다음 예시와 같이 암호화된 클라이언트를 사용하여 patients 컬렉션에 삽입합니다.

patient_document = {
"patientName": "Jon Doe",
"patientId": 12345678,
"patientRecord": {
"ssn": "987-65-4320",
"billing": {
"type": "Visa",
"number": "4111111111111111",
},
"billAmount": 1500,
},
}
encrypted_collection = encrypted_client[encrypted_database_name][encrypted_collection_name]
result = encrypted_collection.insert_one(patient_document)
4

다음 코드 샘플은 암호화된 필드에서 찾기 쿼리를 실행하고 암호가 해독된 데이터를 출력합니다.

const findResult = await encryptedCollection.findOne({
"patientRecord.ssn": "987-65-4320",
});
console.log(findResult);
var ssnFilter = Builders<Patient>.Filter.Eq("patientRecord.ssn", patient.PatientRecord.Ssn);
var findResult = await encryptedCollection.Find(ssnFilter).ToCursorAsync();
Console.WriteLine(findResult.FirstOrDefault().ToJson());
var findResult PatientDocument
err = coll.FindOne(
context.TODO(),
bson.M{"patientRecord.ssn": "987-65-4320"},
).Decode(&findResult)
Patient findResult = collection.find(
new BsonDocument()
.append("patientRecord.ssn", new BsonString("987-65-4320")))
.first();
System.out.println(findResult);
const findResult = await encryptedCollection.findOne({
"patientRecord.ssn": "987-65-4320",
});
console.log(findResult);
find_result = encrypted_collection.find_one({
"patientRecord.ssn": "987-65-4320"
})
print(find_result)

이전 코드 샘플의 출력은 다음과 유사해야 합니다.

{
"_id": {
"$oid": "648b384a722cb9b8392df76a"
},
"name": "Jon Doe",
"record": {
"ssn": "987-65-4320",
"billing": {
"type": "Visa",
"number": "4111111111111111"
},
"billAmount": 1500
},
"__safeContent__": [
{
"$binary": {
"base64": "L1NsYItk0Sg+oL66DBj6IYHbX7tveANQyrU2cvMzD9Y=",
"subType": "00"
}
}
]
}

경고

__safeContent__ 필드를 수정하지 마세요.

__safeContent__ 필드는 Queryable Encryption에 반드시 필요합니다. 이 필드의 내용은 수정하지 마세요.

원격 KMS를 사용한 프로덕션 환경에서 사용할 수 있는 Queryable Encryption에 대한 튜토리얼을 보려면 튜토리얼을 참조하세요.

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

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

  • 참조 페이지에서 Queryable Encryption 구성 요소에 대해 자세히 알아보세요.

  • 암호화 키 및 키 볼트 페이지에서 고객 마스터 키와 데이터 암호화 키가 어떻게 작동하는지 알아보세요.

  • KMS 제공자가 Queryable Encryption 키를 관리하는 방법은 KMS 제공자 페이지에서 확인하세요.

돌아가기

기능