AWS에서 자동 클라이언트 측 필드 레벨 암호화 사용
이 페이지의 내용
개요
이 안내서는 Amazon Web Services(AWS) KMS를 사용하여 클라이언트 측 필드 레벨 암호화(CSFLE) 지원 애플리케이션을 구축하는 방법을 보여줍니다.
이 가이드의 단계를 완료하면 다음과 같은 내용이 표시됩니다:
AWS KMS 인스턴스에서 호스팅되는 고객 마스터 키입니다.
작동하는 클라이언트 애플리케이션으로 고객 마스터 키를 사용하여 암호화된 필드가 있는 문서를 삽입합니다.
시작하기 전에
이 가이드 의 코드를 완료하고 실행 하려면 설치 요구 사항 페이지에 표시된 대로 개발 환경을 설정하다 해야 합니다.
이 가이드 전체에서 코드 예제에는 placeholder 텍스트가 사용됩니다. 예제를 실행하기 전에 placeholder를 자신의 값으로 대체합니다.
예를 들면 다음과 같습니다.
dek_id := "<Your Base64 DEK ID>"
따옴표 사이의 모든 내용을 DEK ID로 바꿉니다.
dek_id := "abc123"
페이지 오른쪽의 Select your language 드롭다운 메뉴에서 코드 예시를 보려는 프로그래밍 언어를 선택합니다.
팁
참조: 전체 적용
이 튜토리얼의 실행 가능한 전체 애플리케이션 코드를 보려면 다음 링크로 이동하십시오.
KMS 설정
// 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
를 사용하여 이 가이드 의 Go 코드를 빌드하거나 실행 때는 항상 cse
빌드 제약 조건을 포함하여 CSFLE 를 활성화 하세요. 빌드 제약 조건을 포함하는 예시 는 다음 shell 명령을 참조하세요.
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.
고객 마스터 키 생성
Amazon Amazon Web Services Web Services 관리 콘솔에 로그인합니다.
Amazon Web Amazon Web Services KMS Services KMS 콘솔 로 이동합니다.
고객 마스터 키 생성
대칭 키 생성 에 대한 공식 Amazon Web Services 설명서에 따라 KMS 새 대칭 키를 생성합니다. . 생성한 키는 고객 마스터 키 입니다. 식별에 도움이 되는 이름과 설명을 선택합니다. 이러한 필드는 CMK 의 기능이나 구성에 영향을 주지 않습니다.
키 생성 프로세스의 Usage Permissions 단계에서 ID 및 액세스 관리(IAM) 정책을 활성화하여 고객 마스터 키에 대한 액세스 권한을 부여하는 다음 기본 키 정책을 적용합니다.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "<ARN of your AWS account principal>" }, "Action": "kms:*", "Resource": "*" } ] }
중요
고객 마스터 키의 Amazon 리소스 이름(ARN) 및 리전을 기록합니다. 이 가이드의 뒷부분에서 이를 사용하게 됩니다.
팁
자세히 알아보기
고객 마스터 키에 대해 자세히 알아보려면 Key & Key Vault를 참조하십시오.
키 정책에 대해 자세히 알아보려면 Amazon Web Services 의 키 정책 KMS 을 참조하세요. 공식 Amazon Web Services 설명서에서 확인 가능합니다.
AWS IAM 사용자 생성
IAM 사용자 생성
사용자 추가 Amazon Web Services 에 대한 공식 Amazon Web Services 문서에 따라 관리 콘솔에서 새 프로그래밍 방식 IAM 사용자를 생성합니다. . 이 IAM 사용자를 CSFLE 지원 애플리케이션 의 서비스 계정으로 사용하게 됩니다. 애플리케이션 은 Amazon Web Services KMS 고객 마스터 키 (CMK)로 데이터 암호화 키(DEK)를 암호화 및 복호화하기 위해 IAM 사용자를 사용하여 로 인증합니다.
중요
자격 증명 기록
IAM 사용자를 생성하는 마지막 단계에서 다음 IAM 자격 증명을 기록해야 합니다.
액세스 키 ID
시크릿 액세스 키
이러한 자격 증명을 기록할 수 있는 기회가 한 번 있습니다. 이 단계에서 이러한 자격 증명을 기록하지 않으면 다른 IAM 사용자를 만들어야 합니다.
권한 부여
IAM 사용자에게 원격 마스터 키에 대한 kms:Encrypt
및 kms:Decrypt
권한을 부여합니다.
중요
새 클라이언트 IAM 사용자는 마스터 키에 대한 관리 권한이 없어야 합니다. 데이터를 안전하게 유지하려면 최소 권한 원칙을 따릅니다.
다음 인라인 정책은 IAM 사용자가 가능한 최소 권한으로 고객 마스터 키를 사용하여 암호화하고 해독할 수 있도록 허용합니다.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["kms:Decrypt", "kms:Encrypt"], "Resource": "<the Amazon Resource Name (ARN) of your remote master key>" } ] }
이전 정책을 IAM 사용자에게 적용하려면 AWS 설명서의 IAM ID 권한 추가하기 가이드를 따르세요.
중요
프로덕션에서 IAM 역할로 인증하기
CSFLE 지원 애플리케이션을 프로덕션 환경에 배포할 때는 IAM 사용자 대신 IAM역할을 사용하여 애플리케이션을 인증합니다.
IAM 역할에 대해 자세히 알아보려면 공식 AWS 설명서의 다음 페이지를 참조하세요.
애플리케이션 생성
키 볼트 collection에 고유 인덱스 만들기
encryption.__keyVault
네임스페이스의 keyAltNames
필드에 고유 인덱스를 만듭니다.
선호하는 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}}, )
새 데이터 암호화 키 생성
AWS KMS 자격 증명 추가
CSFLE 지원 클라이언트 코드에 서비스 계정 자격 증명을 추가합니다.
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var provider = "aws"; var awsKmsOptions = new Dictionary<string, object> { { "accessKeyId", "<Your AWS Access Key ID>" }, { "secretAccessKey", "<Your AWS Secret Access Key>" } }; kmsProviders.Add(provider, awsKmsOptions);
provider := "aws" kmsProviders := map[string]map[string]interface{}{ provider: { "accessKeyId": "<Your AWS Access Key ID>", "secretAccessKey": "<Your AWS Secret Access Key>", }, }
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); String kmsProvider = "aws"; Map<String, Object> providerDetails = new HashMap<>(); providerDetails.put("accessKeyId", new BsonString("<IAM User Access Key ID>")); providerDetails.put("secretAccessKey", new BsonString("<IAM User Secret Access Key>")); kmsProviders.put(kmsProvider, providerDetails);
팁
앞의 코드 예시 와 같이 Amazon Web Services 자격 증명 을 직접 지정하지 않고 제공하는 방법을 학습 보려면 Java MONGODB-Amazon Web Services 설명서를 참조하세요.
const provider = "aws"; const kmsProviders = { aws: { accessKeyId: "<Your AWS Access Key ID>", secretAccessKey: "<Your AWS Secret Access Key>", }, };
provider = "aws" kms_providers = { provider: { "accessKeyId": "<IAM User Access Key ID>", "secretAccessKey": "<IAM User Secret Access Key>", } }
키 정보 추가
고객 마스터 키를 지정하려면 다음 코드를 업데이트하세요.
팁
이 가이드 의 고객 마스터 키 생성 단계에서 고객 마스터 키의 ARN및 리전을 기록했습니다.
var dataKeyOptions = new DataKeyOptions( masterKey: new BsonDocument { { "region", "<Your AWS Key Region>" }, { "key", "<Your AWS Key ARN>" }, });
masterKey := map[string]interface{}{ "key": "<Your AWS Key ARN>", "region": "<Your AWS Key Region>", }
masterKeyProperties.put("provider", new BsonString(kmsProvider)); masterKeyProperties.put("key", new BsonString("<Master Key ARN>")); masterKeyProperties.put("region", new BsonString("<Master Key AWS Region>"));
const masterKey = { key: "<Your AWS Key ARN>", region: "<Your AWS Key Region>", };
master_key = {"region": "<Master Key AWS Region>", "key": "<Master Key ARN>"}
데이터 암호화 키 생성
이 튜토리얼의 1단계에서 선언한 변수를 사용하여 데이터 암호화 키를 생성합니다.
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders ); var clientEncryption = new ClientEncryption(clientEncryptionOptions); 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(). SetMasterKey(masterKey) 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().masterKey(masterKeyProperties)); 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, { masterKey: masterKey, }); 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(provider, master_key) base_64_data_key_id = base64.b64encode(data_key_id) print("DataKeyId [base64]: ", base_64_data_key_id)
팁
자세히 알아보기
AWS KMS를 사용할 때 클라이언트 애플리케이션이 데이터 암호화 키를 생성하는 방법을 보여주는 다이어그램을 보려면 아키텍처를 참조하세요.
AWS KMS에서 호스팅되는 고객 마스터 키로 암호화된 데이터 암호화 키를 만드는 옵션에 대해 자세히 알아보려면 dataKeyOpts Object를 참조하세요.
팁
참조: 코드 완성
데이터 암호화 키 를 만들기 위한 전체 코드를 보려면 Github 리포지토리 를 참조하세요.
데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.
데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.
데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.
데이터 암호화 키를 만들기 위한 전체 코드를 보려면 Github 리포지토리를 참조하세요.
MongoClient 구성
팁
이전 단계에서 생성된 파일과 별도의 파일에서 이 튜토리얼의 나머지 단계를 따르세요.
이 파일 의 전체 코드를 보려면 Github 리포지토리 를 참조하세요.
이 파일의 전체 코드를 보려면 Github 리포지토리를 참조하세요.
이 파일의 전체 코드를 보려면 Github 리포지토리를 참조하세요.
이 파일의 전체 코드를 보려면 Github 리포지토리를 참조하세요.
이 파일의 전체 코드를 보려면 Github 리포지토리를 참조하세요.
키 볼트 collection 네임스페이스 지정하기
키 볼트 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"
AWS 자격 증명 지정
aws
KMS 공급자와 IAM 사용자 자격 증명을 지정합니다.
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var provider = "aws"; var awsKmsOptions = new Dictionary<string, object> { { "accessKeyId", "<Your AWS Access Key ID>" }, { "secretAccessKey", "<Your AWS Secret Access Key>" } }; kmsProviders.Add(provider, awsKmsOptions);
kmsProviders := map[string]map[string]interface{}{ "aws": { "accessKeyId": "<Your AWS Access Key ID>", "secretAccessKey": "<Your AWS Secret Access Key>", }, }
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); String kmsProvider = "aws"; Map<String, Object> providerDetails = new HashMap<>(); providerDetails.put("accessKeyId", "<IAM User Access Key ID>"); providerDetails.put("secretAccessKey", "<IAM User Secret Access Key>"); kmsProviders.put(kmsProvider, providerDetails);
const kmsProviders = { aws: { accessKeyId: "<Your AWS Access Key ID>", secretAccessKey: "<Your AWS Secret Access Key>", }, };
provider = "aws" kms_providers = { "aws": { "accessKeyId": "<IAM User Access Key ID>", "secretAccessKey": "<IAM User Secret Access Key>", } }
중요
알림: 프로덕션에서 IAM 역할로 인증하기
IAM 사용자 대신 IAM 역할을 사용하여 애플리케이션을 인증하려면 KMS 공급자 객체의 자격 증명에 빈 객체를 지정합니다. 이렇게 하면 드라이버가 환경에서 자격 증명을 자동으로 조회하도록 지시합니다.
kmsProviders = { aws: { } };
kmsProviderCredentials.Add("aws", new Dictionary<string, object>);
kmsProviderCredentials := map[string]map[string]interface{}{ "aws": { }, }
kmsProviderCredentials.put("aws", new HashMap<>());
kmsProviders = { aws: { } };
kms_provider_credentials = { "aws": { } }
컬렉션에 대한 암호화 스키마 만들기
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}
자동 암호화 공유 라이브러리의 위치 지정
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를 위한 자동 암호화 공유 라이브러리 페이지를 참조하세요.
MongoClient 생성
이전 단계에서 선언된 변수를 사용하는 다음 자동 암호화 설정으로 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)
암호화된 필드가 있는 문서 삽입하기
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 리포지토리를 참조하세요.
암호화된 필드로 문서 검색하기
이 가이드의 암호화된 필드가 있는 문서 삽입 단계에서 삽입한 암호화된 필드가 있는 문서를 검색합니다.
다음 코드 스니펫은 자동 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 리포지토리를 참조하세요.
자세히 알아보기
CSFLE 작동 방식을 알아보려면 기본 사항을 참조하세요.
이 가이드에 언급된 주제에 대해 자세히 알아보려면 다음 링크를 참조하세요:
CSFLE 구성 요소에 대한 자세한 내용은 참조 페이지에서 확인하세요.
키 및 키 볼트 페이지에서 고객 마스터 키와 데이터 암호화 키가 어떻게 작동하는지 알아보세요.
KMS 제공자가 CSFLE 키를 관리하는 방법은 CSFLE KMS 제공자 페이지에서 확인하세요.