Docs Menu
Docs Home
/ /

튜토리얼: Mongoose 사용한 Queryable Encryption

이 가이드 에서는 Mongoose 사용하여 MongoDB의 Queryable Encryption 기능 구현 애플리케이션 을 만드는 방법을 학습 수 있습니다.

Queryable Encryption 사용하면 문서 필드를 자동으로 암호화하고 해독할 수 있습니다. Queryable Encryption 사용하여 애플리케이션 의 민감한 데이터를 암호화하고, 데이터 필드를 서버 에 무작위로 암호화됨 데이터로 저장 , 암호화됨 필드를 쿼리 수 있습니다. 이 튜토리얼에서는 데이터 상호 작용을 위한 ODM(객체 문서 매퍼) 라이브러리를 제공하는 Mongoose 사용하여 Queryable Encryption 설정하다 방법을 보여줍니다.

이 튜토리얼을 시작하기 전에 다음 전제 조건 작업을 완료하세요.

  • MongoDB Atlas 계정을 만들고 클러스터 구성합니다. 클러스터 가 MongoDB Server 버전 이상에서 실행되는지 7.0 확인합니다. 자세한 학습 은 MongoDB 시작하기 가이드 참조하세요.

  • 자동 암호화 공유 라이브러리를 다운로드합니다. 지침을 보려면 쿼리 분석 구성 요소 설치 및 구성 가이드 참조하세요. 이 지침은 MongoDB 다운로드 센터로 이동하여 라이브러리를 다운로드 데 필요한 양식을 작성하는 방법을 보여줍니다.

  • Node.js v..16 201 이상을 설치합니다.

이 튜토리얼에서는 Mongoose 사용하는 Queryable Encryption 애플리케이션 만드는 방법을 보여줍니다. 이 애플리케이션 환자의 의료 기록을 암호화 및 복호화하고 암호화됨 의료 데이터를 쿼리합니다.

신청서 작성 완료

이 튜토리얼의 전체 샘플 애플리케이션 보려면 GitHub의 mongoose-qe-app 폴더를 참조하세요.

이 섹션의 단계에 따라 프로젝트 종속성을 설치하고, 환경을 구성하고, 애플리케이션 구조를 만듭니다.

1

터미널에서 다음 명령을 실행하여 프로젝트 초기화하고 필요한 종속성을 설치합니다.

mkdir mongoose-qe-app
cd mongoose-qe-app
npm init -y
npm pkg set main="queryable-encryption-tutorial.js"
npm pkg set type="module"
npm pkg set scripts.start="node queryable-encryption-tutorial.js"
npm i mongoose mongodb dotenv mongodb-client-encryption

이 명령은 mongoose-qe-app 프로젝트 디렉토리 만들고 다음 종속성을 설치합니다.

2

프로젝트 루트에서 .env 파일 만들고 다음 코드를 붙여넣습니다.

# MongoDB Connection URI and Shared Library Path
MONGODB_URI="<connection URI>"
SHARED_LIB_PATH="<Automatic Encryption Shared Library path>"
# AWS Credentials
AWS_ACCESS_KEY_ID="<Your AWS access key ID>"
AWS_SECRET_ACCESS_KEY="<Your AWS secret access key>"
AWS_KEY_REGION="<Your AWS key region>"
AWS_KEY_ARN="<Your AWS key ARN>"
# Azure Credentials
AZURE_TENANT_ID="<Your Azure tenant ID>"
AZURE_CLIENT_ID="<Your Azure client ID>"
AZURE_CLIENT_SECRET="<Your Azure client secret>"
AZURE_KEY_NAME="<Your Azure key name>"
AZURE_KEY_VERSION="<Your Azure key version>"
AZURE_KEY_VAULT_ENDPOINT="<Your Azure key vault endpoint>"
# GCP Credentials
GCP_EMAIL="<Your GCP email>"
GCP_PRIVATE_KEY="<Your GCP private key>"
GCP_PROJECT_ID="<Your GCP project ID>"
GCP_LOCATION="<Your GCP location>"
GCP_KEY_RING="<Your GCP key ring>"
GCP_KEY_NAME="<Your GCP key name>"
GCP_KEY_VERSION="<Your GCP key version>"
# KMIP Credentials
KMIP_KMS_ENDPOINT="<Endpoint for your KMIP KMS>"
KMIP_TLS_CA_FILE="<Full path to your KMIP certificate authority file>"
KMIP_TLS_CERT_FILE="<Full path to your client certificate file>"

<connection URI> 자리 표시자를 클러스터 에 연결하는 연결 URI로 바꾸고 <Automatic Encryption Shared Library path> 을 자동 암호화 공유 라이브러리의 전체 경로로 바꿉니다. 경로가 다운로드한 패키지 내부의 lib/mongo_crypt_v1.dylib 를 가리키는지 확인합니다.

.env 템플릿에 나열된 키 관리 시스템(KMS ) 중 하나를 사용하는 경우 해당 자리 표시자 값을 바꿉니다. 그렇지 않으면 이러한 값을 할당하지 않은 상태로 두고 고객 마스터 키 로컬에 저장 수 있습니다. 이 애플리케이션 로컬 고객 마스터 키 파일 생성합니다.

경고

로컬 CMK 스토리지

고객 마스터 키 로컬에 저장 경우 프로덕션 환경에서는 이 애플리케이션 사용하지 마세요. 원격 KMS 없으면 암호화 키 에 무단으로 액세스 하거나 데이터를 해독하는 데 필요한 키를 잃을 위험이 있습니다.

키 관리 시스템

KMS 에 대해 자세히 학습 키 관리 Wikipedia 항목을 참조하세요.

3

mongoose-qe-app 디렉토리 로 이동하여 애플리케이션 로직을 저장 queryable-encryption-tutorial.js 파일 만듭니다. 이 파일 에 다음 코드를 붙여넣습니다.

import 'dotenv/config';
import mongoose from 'mongoose';
import * as qeHelper from './queryable-encryption-helpers.js';
import { MongoClient, ClientEncryption } from 'mongodb';
async function runExample() {
// Paste initial application variables below
// Paste credential and options variables below
// Paste connection and client configuration below
// Paste data key creation code below
// Paste encryption schema below
// Paste the model below
// Paste connection code below
// Paste the insertion operation below
// Paste the encrypted query below
await connection.close();
console.log('Connection closed.');
}
runExample().catch(console.dir);

그런 다음 queryable-encryption-helpers.js 이라는 파일 만들고 다음 코드를 붙여넣습니다.

import 'dotenv/config';
import { writeFileSync, readFileSync, existsSync } from 'fs';
import { randomBytes } from 'crypto';
export async function dropExistingDatabase(client, databaseName) {
const database = client.db(databaseName);
await database.dropDatabase();
}
// Paste helper methods below

이 파일 애플리케이션 에 대한 dropExistingDatabase() 헬퍼 함수가 포함되어 있습니다. 이 튜토리얼의 이후 단계에서는 헬퍼 함수를 추가하는 방법을 설명합니다.

4

queryable-encryption-tutorial.js 파일 의 runExample() 함수에 다음 코드를 붙여넣어 초기 데이터베이스 및 암호화 변수를 지정합니다.

const kmsProviderName = '<KMS provider>';
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>' 자리 표시자를 키 제공자 ( 'aws', 'azure', 'gcp' 또는 'kmip')로 바꿉니다. 고객 마스터 키 로컬에 저장 하려면 이 값을 'local'로 설정하다 .

이 코드는 다음 변수를 미리 채웁니다.

  • keyVaultDatabaseName - 데이터 암호화 키(DEK)를 저장하는 MongoDB 의 데이터베이스 입니다. 이 튜토리얼에서는 encryption 데이터베이스 사용합니다.

  • keyVaultCollectionName - DEK를 저장하는 MongoDB 의 컬렉션 입니다. 이 코드에서는 이 변수를 로 __keyVault 설정하고, 사용자 컬렉션 과 구분하기 위해 밑줄이 앞에 붙습니다.

  • keyVaultNamespace - DEK를 저장하는 MongoDB 의 네임스페이스 . 이 변수는 keyVaultDatabaseName keyVaultCollectionName 마침표로 구분된 및 변수로 구성됩니다.

  • encryptionDatabaseName - 암호화됨 데이터를 저장하는 MongoDB 의 데이터베이스 입니다. 이 튜토리얼에서는 medicalRecords 데이터베이스 사용합니다.

  • encryptionCollectionName - 암호화됨 데이터를 저장하는 MongoDB 의 컬렉션 입니다. 이 튜토리얼에서는 patients 컬렉션 사용합니다.

프로젝트 구조를 설정한 후 이 섹션의 단계에 따라 KMS 제공자 자격 증명 및 암호화 옵션을 구성합니다.

1

queryable-encryption-helpers.js 파일 에 getKMSProviderCredentials() 함수를 추가합니다. 이 함수는 키 관리 시스템 제공자 의 자격 증명 조회하거나, KMS 제공자 사용하지 않는 경우 로컬 고객 마스터 키 파일 생성합니다.

dropExistingDatabase() 함수 뒤에 다음 코드를 붙여넣습니다.

export function getKMSProviderCredentials(kmsProviderName) {
let kmsProviders;
switch (kmsProviderName) {
case 'aws':
kmsProviders = {
aws: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID, // Your AWS access key ID
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, // Your AWS secret access key
},
};
return kmsProviders;
case 'azure':
kmsProviders = {
azure: {
tenantId: process.env.AZURE_TENANT_ID, // Your Azure tenant ID
clientId: process.env.AZURE_CLIENT_ID, // Your Azure client ID
clientSecret: process.env.AZURE_CLIENT_SECRET, // Your Azure client secret
},
};
return kmsProviders;
case 'gcp':
kmsProviders = {
gcp: {
email: process.env.GCP_EMAIL, // Your GCP email
privateKey: process.env.GCP_PRIVATE_KEY, // Your GCP private key
},
};
return kmsProviders;
case 'kmip':
kmsProviders = {
kmip: {
endpoint: process.env.KMIP_KMS_ENDPOINT, // Your KMIP KMS endpoint
},
};
return kmsProviders;
case 'local':
(function () {
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}`
);
}
}
})();
try {
// 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,
},
};
} catch (err) {
throw new Error(
`Unable to read the Customer Master Key due to the following error: ${err}`
);
}
return kmsProviders;
default:
throw new Error(
`Unrecognized value for KMS provider name \'${kmsProviderName}\' encountered while retrieving KMS credentials.`
);
}
}

getKMSProviderCredentials() 함수는 AWS, Azure, GCP, KMIP 및 로컬 키 저장 포함한 여러 KMS 제공자를 지원합니다.

2

queryable-encryption-helpers.js 파일 에 getCustomerMasterKeyCredentials() 함수를 추가합니다. 이 함수는 KMS 제공자 기반으로 고객 마스터 키 자격 증명 검색합니다.

getKMSProviderCredentials() 함수 뒤에 다음 코드를 붙여넣습니다.

export function getCustomerMasterKeyCredentials(kmsProviderName) {
let customerMasterKeyCredentials;
switch (kmsProviderName) {
case 'aws':
customerMasterKeyCredentials = {
key: process.env.AWS_KEY_ARN, // Your AWS Key ARN
region: process.env.AWS_KEY_REGION, // Your AWS Key Region
};
return customerMasterKeyCredentials;
case 'azure':
customerMasterKeyCredentials = {
keyVaultEndpoint: process.env.AZURE_KEY_VAULT_ENDPOINT, // Your Azure Key Vault Endpoint
keyName: process.env.AZURE_KEY_NAME, // Your Azure Key Name
};
return customerMasterKeyCredentials;
case 'gcp':
customerMasterKeyCredentials = {
projectId: process.env.GCP_PROJECT_ID, // Your GCP Project ID
location: process.env.GCP_LOCATION, // Your GCP Key Location
keyRing: process.env.GCP_KEY_RING, // Your GCP Key Ring
keyName: process.env.GCP_KEY_NAME, // Your GCP Key Name
};
return customerMasterKeyCredentials;
case 'kmip':
case 'local':
customerMasterKeyCredentials = {};
return customerMasterKeyCredentials;
default:
throw new Error(
`Unrecognized value for KMS provider name \'${kmsProviderName}\' encountered while retrieving Customer Master Key credentials.`
);
}
}

이 함수는 선택한 KMS 제공자 에 해당하는 고객 마스터 키 자격 증명 구성합니다.

3

queryable-encryption-helpers.js 파일 에 getAutoEncryptionOptions() 함수를 추가합니다. 이 함수는 애플리케이션 에 대한 자동 암호화 옵션을 구성합니다.

getCustomerMasterKeyCredentials() 함수 뒤에 다음 코드를 붙여넣습니다.

export async function getAutoEncryptionOptions(
kmsProviderName,
keyVaultNamespace,
kmsProviders
) {
if (kmsProviderName === 'kmip') {
const tlsOptions = {
kmip: {
tlsCAFile: process.env.KMIP_TLS_CA_FILE, // Path to your TLS CA file
tlsCertificateKeyFile: process.env.KMIP_TLS_CERT_FILE, // Path to your TLS certificate key file
},
};
const extraOptions = {
cryptSharedLibPath: process.env.SHARED_LIB_PATH, // Path to your Automatic Encryption Shared Library
};
const autoEncryptionOptions = {
keyVaultNamespace,
kmsProviders,
extraOptions,
tlsOptions,
};
return autoEncryptionOptions;
} else {
const extraOptions = {
cryptSharedLibPath: process.env.SHARED_LIB_PATH, // Path to your Automatic Encryption Shared Library
};
const autoEncryptionOptions = {
keyVaultNamespace,
kmsProviders,
extraOptions,
};
return autoEncryptionOptions;
}
}
4

이제 헬퍼 함수를 정의했으므로 이를 사용하여 메인 애플리케이션 파일 에서 자격 증명 에 액세스 할 수 있습니다.

queryable-encryption-tutorial.js 파일 로 이동하여 // Paste credential and options variables below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const kmsProviderCredentials =
qeHelper.getKMSProviderCredentials(kmsProviderName);
const customerMasterKeyCredentials =
qeHelper.getCustomerMasterKeyCredentials(kmsProviderName);
const autoEncryptionOptions = await qeHelper.getAutoEncryptionOptions(
kmsProviderName,
keyVaultNamespace,
kmsProviderCredentials
);

이 코드는 헬퍼 함수를 호출하여 Queryable Encryption 구성하는 데 사용되는 KMS 제공자 자격 증명, 고객 마스터 키 자격 증명 및 자동 암호화 옵션을 조회 .

암호화 설정을 구성한 후 이 섹션의 단계에 따라 MongoDB 연결을 설정하다 하고, 데이터 키를 만들고, 암호화됨 스키마 정의합니다.

1

MongoDB 연결 및 클라이언트 설정하다 하려면 queryable-encryption-tutorial.js 파일 로 이동하여 // Paste connection and client configuration below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const connection = mongoose.createConnection();
const client = new MongoClient(uri);
const clientEncryption = new ClientEncryption(
client,
autoEncryptionOptions
);
await qeHelper.dropExistingDatabase(client, encryptedDatabaseName);
await qeHelper.dropExistingDatabase(client, keyVaultDatabaseName);

이 코드는 암호화됨 작업을 위한 Mongoose 연결, 키 관리 위한 MongoDB 클라이언트 , 데이터 키 생성을 위한 ClientEncryption 인스턴스 생성합니다. 또한 튜토리얼을 깔끔하게 설정 수 있도록 기존 데이터베이스를 모두 삭제합니다.

2

필요한 데이터 키를 만들려면 // Paste data key creation code below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const keyId1 = await clientEncryption.createDataKey(
kmsProviderName, {
masterKey: customerMasterKeyCredentials,
});
const keyId2 = await clientEncryption.createDataKey(
kmsProviderName, {
masterKey: customerMasterKeyCredentials,
});
const keyId3 = await clientEncryption.createDataKey(
kmsProviderName, {
masterKey: customerMasterKeyCredentials,
});

이 코드는 환자 문서의 서로 다른 필드를 암호화하는 데 사용되는 3개의 데이터 암호화 키를 생성합니다. 암호화됨 각 필드 자체 데이터 키가 필요합니다.

3

암호화됨 스키마 정의를 만들려면 // Paste encryption schema below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const patientSchema = new mongoose.Schema({
patientName: {
type: String,
required: true
},
patientId: {
type: Number,
required: true
},
patientRecord: {
ssn: {
type: String,
encrypt: {
keyId: keyId1,
queries: { queryType: 'equality' }
}
},
billing: {
type: {
type: String,
encrypt: {
keyId: keyId2,
}
},
number: {
type: String,
encrypt: {
keyId: keyId3
}
}
},
billAmount: Number
}
}, {
encryptionType: 'queryableEncryption',
collection: encryptedCollectionName
});

이 스키마 patients 컬렉션 에 있는 문서의 구조를 정의하고 다음과 같은 암호화됨 필드를 지정합니다.

  • patientRecord.ssn: 동일성 쿼리를 위해 암호화 및 구성

  • patientRecord.billing.type: 암호화되었지만 쿼리할 수 없음

  • patientRecord.billing.number: 암호화되었지만 쿼리할 수 없음

4

patients 컬렉션 나타내는 Patient 이라는 새 모델을 만들고 모델에 암호화 스키마 등록합니다. 모델을 만들려면 // Paste the model below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const Patient = connection.model('Patient', patientSchema);

이 코드는 데이터베이스 작업을 수행할 때 필드의 자동 암호화 및 암호 해독을 처리하는 Mongoose 모델을 생성합니다.

5

모델을 등록한 후 // Paste connection code below 코드 주석 뒤에 다음 코드를 붙여넣어 데이터베이스 연결을 설정할 수 있습니다.

await connection.openUri(uri, {
autoEncryption: autoEncryptionOptions,
dbName: encryptedDatabaseName
});

이렇게 하면 자동 암호화 활성화된 medicalRecords 데이터베이스 에 대한 연결이 설정됩니다.

애플리케이션 과 데이터베이스 연결을 구성한 후 이 섹션의 단계에 따라 암호화됨 문서를 삽입하고 쿼리 .

1

암호화됨 필드가 있는 문서 삽입하려면 queryable-encryption-tutorial.js 파일 로 이동하여 // Paste the insertion operation below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const patientDocument = {
patientName: 'Jon Doe',
patientId: 12345678,
patientRecord: {
ssn: '987-65-4320',
billing: {
type: 'Visa',
number: '4111111111111111',
},
billAmount: 1500,
},
};
const result = await Patient.create(patientDocument);
if (result) {
console.log('Successfully inserted the patient document.');
console.log('Document ID:', result._id);
}

Queryable Encryption 문서 MongoDB 에 저장하기 전에 patientRecord.ssnpatientRecord.billing 필드를 자동으로 암호화합니다.

2

암호화됨 필드 쿼리 하려면 // Paste the encrypted query below 코드 주석 뒤에 다음 코드를 붙여넣습니다.

const findResult = await Patient.findOne({
'patientRecord.ssn': '987-65-4320',
});
console.log('Found patient:');
console.log(findResult);

이 코드는 암호화됨 patientRecord.ssn 필드 에 대해 동등성 쿼리 수행합니다.

3

마지막으로 mongoose-qe-app 디렉토리 에서 다음 명령을 실행 하여 이전 단계에서 정의된 암호화됨 작업을 실행 수 있습니다.

npm start

성공적인 하면 명령 출력이 다음 예시 와 유사합니다.

Successfully inserted the patient document.
Document ID: new ObjectId('...')
Found patient:
{
patientRecord: {
billing: { type: 'Visa', number: '4111111111111111' },
ssn: '987-65-4320',
billAmount: 1500
},
_id: new ObjectId('...'),
patientName: 'Jon Doe',
patientId: 12345678,
__v: 0,
__safeContent__: [
Binary.createFromBase64('EGzhQwBpf1B6W9udskSxJ8kwEEnF5P+SJPZ6ygQ9Ft8=', 0)
]
}
Connection closed.

Mongoose Queryable Encryption 튜토리얼을 완료한 것을 축하합니다! 이제 Queryable Encryption 사용하여 문서 필드를 자동으로 암호화하고 해독하는 샘플 Mongoose 애플리케이션 생겼습니다. 애플리케이션 은 서버 사이드에서 민감한 데이터를 암호화하고 클라이언트 사이드에서 데이터를 쿼리합니다.

Queryable Encryption 및 Mongoose 에 대해 자세히 학습 다음 리소스를 참조하세요.

  • MongoDB Server매뉴얼에서 더 많은 운전자 Queryable Encryption 튜토리얼을 확인하세요.

  • Mongoose 시작하기 튜토리얼에서 Queryable Encryption 없이 Mongoose 사용하는 애플리케이션 만드는 방법을 알아보세요.

  • Mongoose 에 대한 자세히 보기 Mongoose 설명서를 참조하세요.

돌아가기

Mongoose 시작하기

이 페이지의 내용