개요
이 가이드 에서는 클라이언트 사이드 필드 레벨 암호화 (CSFLE)를 사용하여 데이터를 암호화하는 방법을 학습 수 있습니다. CSFLE를 사용하면 네트워크를 통해 MongoDB 로 전송하기 전에 애플리케이션 의 데이터를 암호화할 수 있습니다. 즉, 암호화되지 않은 형태의 데이터에 액세스 할 수 있는 MongoDB 제품은 없습니다.
다음 메커니즘 중 하나를 사용하여 CSFLE를 설정하다 수 있습니다.
자동 암호화: 필드 암호화 방법을 지정하지 않고도 암호화됨 읽기 및 쓰기 (write) 작업을 수행할 수 있습니다.
명시적 암호화 : 애플리케이션 전체에서 지정된 암호화 로직을 사용하여 암호화됨 읽기 및 쓰기 (write) 작업을 수행할 수 있습니다.
이 가이드 자동 암호화 사용하여 CSFLE를 설정하다 방법을 설명합니다.
설치 종속성
Mongoid와 함께 CSFLE를 사용하려면 먼저 다음 종속성을 설치해야 합니다.
libmongocrypt
Ruby 운전자 v2.19 이상을 사용하는 경우 자동 암호화 공유 라이브러리. 또는 Ruby 운전자 v2.18 이전 버전을 사용하는 경우
mongocryptd
입니다.ffi
다음 섹션에서는 이러한 종속성을 설치하는 방법에 대해 자세히 설명합니다.
libmongocrypt
You can install libmongocrypt
by adding the libmongocrypt-helper gem to your Gemfile
or by downloading the library manually.
gem 파일 추가하여 libmongocrypt
를 설치하려면 애플리케이션 있는 폴더로 이동하여 셸 에서 다음 명령을 실행 .
gem install libmongocrypt-helper --pre
참고
libmongocrypt-helper
의 버전 번호에 문자가 포함될 수 있으며, 이는 Ruby 의 시험판 버전을 나타내는 --pre
플래그가 필요합니다.
공유 라이브러리(드라이버 v2.19 이상)
다음 단계에서는 자동 암호화 공유 라이브러리를 설치하는 방법을 자세히 설명합니다.
(current)
태그를 지정하다 로 표시된Version
드롭다운에서 최신 현재 버전을 선택합니다.Platform
드롭다운에서 플랫폼을 선택합니다.Package
드롭다운에서crypt_shared
을 선택합니다.Download
버튼을 클릭하여 공유 라이브러리를 다운로드 .
파일 다운로드 후 내용을 추출하고 애플리케이션 액세스 할 수 있는 위치 에 파일 저장합니다. 그런 다음 다음 예시 와 같이 애플리케이션 에서 mongoid.yml
파일 이 라이브러리를 가리 점 도록 구성합니다.
development: clients: default: options: auto_encryption_options: extra_options: crypt_shared_lib_path: '<Path to Shared Library>'
mongocryptd(드라이버 v2.18 이하)
Ruby 운전자 버전 2.18 이하를 사용하는 경우 자동 암호화 공유 라이브러리 대신 mongocryptd
를 사용해야 합니다. mongocryptd
은(는 ) MongoDB Server 의 엔터프라이즈 빌드와 함께 사전 패키징되어 제공됩니다. 를 설치하고 구성하는 방법에 mongocryptd
대한 지침은 MongoDB Server 매뉴얼의 mongocryptd 설치 가이드 참조하세요.
ffi
Mongoid uses the ffi gem to call functions from libmongocrypt
. Add the gem to your Gemfile
by running the following command in your shell:
gem 'ffi'
고객 마스터 키 생성
데이터를 암호화하고 해독하려면 먼저 고객 마스터 키 (CMK)를 생성해야 합니다. CMK 는 DEK 암호화하는 데 사용하는 키입니다. CMK 에 대한 액세스 없으면 클라이언트 애플리케이션 암호화됨 데이터와 연결된 DEK를 해독할 수 없습니다.
다음 Ruby 코드를 실행 하여 테스트 목적으로 로컬 CMK 로 사용할 로컬에 저장된 키를 생성할 수 있습니다.
require 'securerandom' SecureRandom.hex(48)
경고
프로덕션 환경에서 로컬 CMK 사용하는 것은 안전하지 않습니다. 프로덕션 환경의 경우 원격 KMS 사용하여 CMK 생성하고 저장 .
KMS 제공자에 대해 자세히 학습 MongoDB Server 매뉴얼의 KMS 제공자 가이드 참조하세요.
클라이언트 구성
CSFLE를 구현 하려면 MongoDB 클라이언트 구성해야 합니다. CSFLE에 대한 클라이언트 구성하려면 mongoid.yml
파일 에 다음 코드를 추가합니다.
development: clients: default: uri: "<connection string>" options: auto_encryption_options: # This key enables automatic encryption key_vault_namespace: 'encryption.__keyVault' # Database and collection in which to store data keys kms_providers: # Tells the driver where to obtain master keys local: # Specifies that the key is local key: "<Path to your CMK>" extra_options: crypt_shared_lib_path: '<Path to Shared Library>' # Only required for Ruby versions 2.19 or later
참고
앞의 코드 예시 에서는 괄호(<>
)로 묶인 자리 표시자를 바꿔야 합니다.
데이터 암호화 키 생성
DEK 는 문서의 필드를 암호화하는 데 사용하는 키입니다. MongoDB CMK 로 암호화됨 DEK를 키 볼트 컬렉션 에 BSON 문서로 저장합니다. 키 관리 클라이언트 사이드 이루어지고 고객이 제어하기 때문에 MongoDB DEK를 절대 복호화할 수 없습니다.
Mongoid에서 DEK를 만들려면 다음 예시 와 같이 db:mongoid:encryption:create_data_key
rake 작업 사용할 수 있습니다.
rake db:mongoid:encryption:create_data_key
생성하려는 키 수만큼 앞의 명령을 반복하여 여러 DEK를 만들 수 있습니다.
DEK의 대체 이름을 제공할 수도 있습니다. 이를 통해 필드에 대한 암호화 구성할 때 이름으로 DEK를 참조하고 런타임에 DEK를 필드 에 동적으로 할당할 수 있습니다.
다음 예시 새 DEK를 생성할 때 대체 이름을 생성합니다.
rake db:mongoid:encryption:create_data_key -- --key-alt-name=<custom DEK name>
암호화 스키마 구성
다음 예시 와 같이 모델의 필드 정의에 encrypt
옵션을 추가하고 deterministic
및 key_id
옵션을 지정하여 암호화할 필드를 지정할 수 있습니다.
class Patient include Mongoid::Document include Mongoid::Timestamps encrypt_with key_id: '<data encryption key>' # This field is not encrypted field :category, type: String # This field is encrypted by using AEAD_AES_256_CBC_HMAC_SHA_512-Random # algorithm field :passport_id, type: String, encrypt: { deterministic: false } # This field is encrypted by using AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic # algorithm field :blood_type, type: String, encrypt: { deterministic: true } # This field is encrypted by using AEAD_AES_256_CBC_HMAC_SHA_512-Random # algorithm and a different data key field :ssn, type: Integer, encrypt: { deterministic: false, key_id: '<New key ID' } embeds_one :insurance end class Insurance include Mongoid::Document include Mongoid::Timestamps field :insurer, type: String # This field is encrypted using AEAD_AES_256_CBC_HMAC_SHA_512-Random # algorithm using a key with an alternate name stored in the policy_number_key field field :policy_number, type: Integer, encrypt: { deterministic: false, key_name_field: :policy_number_key } embedded_in :patient end
참고
Rails 애플리케이션 개발하는 경우 mongoid.yml
파일 에서 preload_models
옵션을 true
로 설정하는 것이 좋습니다. 이렇게 하면 데이터를 읽거나 쓰기 전에 Mongoid가 모든 모델을 로드하고 암호화 스키마 구성할 수 있습니다.
제한 사항
Mongoid와 함께 CSFLE를 사용할 때는 다음과 같은 제한 사항이 적용 .
Mongoid는
embeds_many
연관 관계의 암호화 지원 하지 않습니다.:key_name_field
옵션을 사용하는 경우 비결정적 알고리즘 사용하여 필드 암호화해야 합니다. 필드 결정론적으로 암호화하려면 대신:key_id
옵션을 지정해야 합니다.MongoDB Server 매뉴얼의 CSFLE 제한 사항 페이지에 나열된 제한 사항은 Mongoid에도 적용 .
데이터와 함께 작업하기
일반적으로 자동 CSFLE는 애플리케이션 에서 투명하게 작동합니다. 애플리케이션 CSFLE에 맞게 구성한 후에는 평소와 같이 문서를 생성할 수 있으며 Mongoid는 구성에 따라 문서를 자동으로 암호화하고 해독합니다.
다음 예시 CSFLE용으로 구성된 애플리케이션 에서 새 Patient
문서 만듭니다. 그런 다음 데이터베이스 에 연결되었지만 CSFLE가 문서 를 읽도록 구성되지 않은 unencrypted_client
클라이언트 사용합니다.
Patient.create!( category: 'ER', passport_id: '123456', blood_type: 'AB+', ssn: 98765, insurance: Insurance.new(insurer: 'TK', policy_number: 123456, policy_number_key: 'my_data_key') ) # Fields are encrypted in the database unencrypted_client['patients'].find.first
{"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4292'), "category"=>"ER", "passport_id"=><BSON::Binary:0x404080 type=ciphertext data=0x012889b2cb0b1341...>, "blood_type"=><BSON::Binary:0x404560 type=ciphertext data=0x022889b2cb0b1341...>, "ssn"=><BSON::Binary:0x405040 type=ciphertext data=0x012889b2cb0b1341...>, "insurance"=>{"_id"=>BSON::ObjectId('6446a1d046ebfd701f9f4293'), "insurer"=>"TK", "policy_number"=><BSON::Binary:0x405920 type=ciphertext data=0x012889b2cb0b1341...>}, "policy_number_key"=>"my_data_key"}
앞의 예시 에서 unencrypted_client
클라이언트 암호화됨 필드를 읽을 수 없습니다. 그러나 CSFLE용으로 구성된 클라이언트 로 문서 쿼리 하면 Mongoid가 자동으로 필드를 해독합니다.
암호화 키 회전
rewrap_many_data_key
Ruby 운전자 메서드를 사용하여 암호화 키를 순환할 수 있습니다. 이 방법은 여러 데이터 암호화 키를 자동으로 해독하고 지정된 CMK 사용하여 다시 암호화합니다. 그런 다음 키 볼트 컬렉션 에서 순환된 키를 업데이트합니다.
rewrap_many_data_key
메서드는 다음 매개 변수를 사용합니다.
필터는 회전할 필드를 지정하는 데 사용됩니다. 지정된 필터하다 와 일치하는 데이터 키가 없으면 키가 순환되지 않습니다. 키 볼트 컬렉션 의 모든 키를 순환시키려면 필터하다 생략합니다.
DEK를 다시 암호화하는 데 사용할 새 CMK 나타내는 객체입니다. 현재 CMK를 사용하여 데이터 키를 회전하려면 이 객체 생략합니다.
다음 예시 Amazon Web Services KMS 사용하여 암호화 키를 순환합니다.
# Create a key vault client key_vault_client = Mongo::Client.new('<connection string>') # Create the encryption object encryption = Mongo::ClientEncryption.new( key_vault_client, key_vault_namespace: 'encryption.__keyVault', kms_providers: { aws: { "accessKeyId": "<IAM User Access Key ID>", "secretAccessKey": "<IAM User Secret Access Key>" } } ) encryption.rewrap_many_data_key( {}, # Empty filter to rewrap all keys { provider: 'aws', master_key: { region: 'us-east-2', key: 'arn:aws:kms:us-east-2:...' } } )
기존 프로젝트에 자동 암호화 추가
Mongoid를 사용한 자동 CSFLE는 제자리에서 암호화 지원합니다. 기존 데이터베이스 에서 암호화 활성화 하면서 암호화되지 않은 데이터를 읽을 수 있습니다. 그러나 암호화 활성화 모든 새 데이터가 암호화됨 되며 모든 쿼리 작업에는 암호화됨 문서만 사용됩니다. 즉, 암호화 활성화하기 전에 일부 문서를 저장한 경우 쿼리에서 모든 문서가 반환되지 않을 수 있습니다.
다음 예시 암호화됨 문서 한 개와 암호화되지 않은 문서 한 개가 있는 컬렉션 쿼리합니다.
# Print all documents in the collection. The first document is unencrypted, and # the second is encrypted. Patient.all.to_a # => # [#<Patient _id: 644937ac46ebfd02468e58c8, category: "ER", passport_id: "DE-1257", blood_type: "AB+", ssn: 123456>, # #<Patient _id: 644937c946ebfd029309b912, category: "ER", passport_id: "AT-1545", blood_type: "AB+", ssn: 987654>] # Querying for documents with a CSFLE-enabled client returns only the encrypted document Patient.where(blood_type: 'AB+').to_a # => [#<Patient _id: 644937c946ebfd029309b912, category: "ER", passport_id: "AT-1545", blood_type: "AB+", ssn: 987654>]
CSFLE 지원 클라이언트 로 모든 데이터를 읽은 다음 다시 기록하여 컬렉션 의 기존 데이터를 암호화할 수 있습니다. 이 작업을 수행할 때는 기존의 모든 데이터가 예상 유형인지, 빈 값이 nil
(으)로 설정하다 있지 않은지 확인하세요.
추가 정보
CSFLE에 대해 자세히 학습 MongoDB Server 매뉴얼의 클라이언트 측 필드 레벨 암호화 가이드 참조하세요.
애플리케이션 에서 Mongoid를 구성하는 방법에 대해 자세히 학습 애플리케이션 구성 가이드 참조하세요.