Active Record 암호화
이 가이드는 Active Record를 사용하여 데이터베이스 정보를 암호화하는 방법을 다룹니다.
이 가이드를 읽고 나면 다음을 알 수 있습니다:
- Active Record로 데이터베이스 암호화를 설정하는 방법.
- 암호화되지 않은 데이터를 마이그레이션하는 방법.
- 다양한 암호화 체계가 공존하도록 하는 방법.
- API 사용 방법.
- 라이브러리 구성 및 확장 방법.
Active Record는 애플리케이션 수준의 암호화를 지원합니다. 이는 어떤 속성을 암호화해야 하는지 선언하고, 필요할 때 투명하게 암호화 및 복호화하는 것입니다. 암호화 계층은 데이터베이스와 애플리케이션 사이에 있습니다. 애플리케이션은 암호화되지 않은 데이터에 액세스하지만, 데이터베이스에는 암호화된 데이터가 저장됩니다.
애플리케이션 수준에서 데이터를 암호화해야 하는 이유?
Active Record 암호화는 애플리케이션의 중요한 정보를 보호하기 위해 존재합니다. 일반적인 예는 사용자의 개인 식별 정보입니다. 그렇다면 데이터베이스 자체가 이미 암호화되어 있다면 애플리케이션 수준의 암호화를 왜 해야 할까요?
즉각적인 실용적 이점으로, 중요한 속성을 암호화하면 추가적인 보안 계층이 생깁니다. 예를 들어 공격자가 데이터베이스, 데이터베이스 스냅샷 또는 애플리케이션 로그에 액세스하더라도 암호화된 정보를 이해할 수 없습니다. 또한 암호화를 통해 개발자가 애플리케이션 로그에서 사용자의 중요한 데이터를 실수로 노출하는 것을 방지할 수 있습니다.
그러나 더 중요한 것은 Active Record 암호화를 사용하면 애플리케이션 코드 수준에서 중요한 정보를 정의할 수 있다는 것입니다. Active Record 암호화를 통해 애플리케이션 및 애플리케이션의 데이터를 소비하는 서비스에서 데이터 액세스를 세부적으로 제어할 수 있습니다. 예를 들어 암호화된 데이터를 보호하는 감사 가능한 Rails 콘솔을 고려해 보거나 컨트롤러 매개변수에 자동으로 필터링되는 내장 시스템을 확인해 보세요.
기본 사용법
설정
bin/rails db:encryption:init
명령을 실행하여 랜덤 키 세트를 생성합니다:
$ bin/rails db:encryption:init
대상 환경의 자격 증명에 다음 항목을 추가하세요:
active_record_encryption:
primary_key: EGY8WhulUOXixybod7ZWwMIL68R9o5kC
deterministic_key: aPA5XyALhf75NNnMzaspW7akTfZp0lPY
key_derivation_salt: xEY0dt6TZcAMg52K7O84wYzkjvbA62Hz
이 값은 기존 Rails 자격 증명에 생성된 값을 복사하여 붙여넣어 저장할 수 있습니다. 또는 이러한 값을 환경 변수와 같은 다른 소스에서 구성할 수 있습니다:
config.active_record.encryption.primary_key = ENV['ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY'] config.active_record.encryption.deterministic_key = ENV['ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY'] config.active_record.encryption.key_derivation_salt = ENV['ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT']
참고: 이렇게 생성된 값은 32바이트 길이입니다. 직접 생성하는 경우 기본 키는 최소 12바이트, 솔트는 최소 20바이트를 사용해야 합니다.
암호화된 속성 선언
암호화 가능한 속성은 모델 수준에서 정의됩니다. 이는 동일한 이름의 열로 백업되는 일반적인 Active Record 속성입니다.
class Article < ApplicationRecord encrypts :title end
라이브러리는 이러한 속성을 투명하게 암호화하여 데이터베이스에 저장하고, 필요할 때 복호화합니다:
article = Article.create title: "Encrypt it all!" article.title # => "Encrypt it all!"
그러나 내부적으로 실행된 SQL은 다음과 같습니다:
INSERT INTO `articles` (`title`) VALUES ('{\"p\":\"n7J0/ol+a7DRMeaE\",\"h\":{\"iv\":\"DXZMDWUKfp3bg/Yu\",\"at\":\"X1/YjMHbHD4talgF9dt61A==\"}}')
중요: 저장 및 열 크기에 대하여
암호화에는 Base64 인코딩과 암호화된 페이로드와 함께 저장되는 메타데이터로 인해 추가 공간이 필요합니다. 내장된 엔벨로프 암호화 키 공급자를 사용하는 경우 최악의 경우 오버헤드는 약 255바이트 정도로 추정할 수 있습니다. 이 오버헤드는 더 큰 크기에서는 무시할 수 있습니다. 단순히 희석되기 때문만이 아니라 라이브러리가 기본적으로 압축을 사용하여 더 큰 페이로드에 대해 최대 30%의 저장 공간 절감 효과를 제공하기 때문입니다.
문자열 열 크기에 대한 중요한 우려 사항이 있습니다: 현대 데이터베이스에서 열 크기는 문자 수를 결정하며 바이트 수가 아닙니다. 예를 들어 UTF-8에서 각 문자는 최대 4바이트를 차지할 수 있으므로, 잠재적으로 UTF-8을 사용하는 데이터베이스의 열은 바이트 수 기준으로 4배까지 저장할 수 있습니다. 이제 암호화된 페이로드는 Base64로 직렬화된 이진 문자열이므로 일반 string
열에 저장할 수 있습니다. ASCII 바이트 시퀀스이므로 암호화된 열은 일반 버전 크기의 4배까지 차지할 수 있습니다. 따라서 데이터베이스에 저장되는 바이트가 동일하더라도 열은 4배 더 커야 합니다.
실제로 이는 다음을 의미합니다:
- 서구 알파벳(주로 ASCII 문자)으로 작성된 짧은 텍스트를 암호화할 때는 255바이트의 추가 오버헤드를 고려해야 합니다.
- 키릴 문자와 같은 비서구 알파벳으로 작성된 짧은 텍스트를 암호화할 때는 열 크기를 4배 늘려야 합니다. 저장 오버헤드는 최대 255바이트입니다.
- 긴 텍스트를 암호화할 때는 열 크기 문제를 무시할 수 있습니다.
몇 가지 예:
암호화할 내용 | 원래 열 크기 | 권장 암호화된 열 크기 | 최악의 경우 저장 오버헤드 |
---|---|---|---|
이메일 주소 | string(255) | string(510) | 255바이트 |
이모지 시퀀스 | string(255) | string(1020) | 255바이트 |
비서구 알파벳으로 작성된 텍스트 요약 | string(500) | string(2000) | 255바이트 |
임의의 긴 텍스트 | text | text | 무시할 수 있음 |
결정론적 및 비결정론적 암호화
기본적으로 Active Record 암호화는 비결정론적 접근 방식을 사용합니다. 비결정론적이라는 의미는 동일한 비밀번호로 동일한 내용을 두 번 암호화하면 서로 다른 암호문이 생성된다는 것입니다. 이 접근 방식은 암호문 분석을 더 어렵게 만들고 데이터베이스 쿼리를 불가능하게 합니다.
deterministic:
옵션을 사용하면 초기화 벡터를 결정론적으로 생성하여 암호화된 데이터를 쿼리할 수 있습니다.
class Author < ApplicationRecord encrypts :email, deterministic: true end Author.find_by_email("some@email.com") # 모델을 정상적으로 쿼리할 수 있습니다.
비결정론적 접근 방식은 데이터를 쿼리할 필요가 없는 경우 권장됩니다.
참고: 비결정론적 모드에서 Active Record는 256비트 키와 랜덤 초기화 벡터를 사용하는 AES-GCM을 사용합니다. 결정론적 모드에서는 키와 암호화할 내용의 HMAC-SHA-256 다이제스트를 사용하여 초기화 벡터를 생성합니다.
참고: deterministic_key
를 생략하면 결정론적 암호화를 비활성화할 수 있습니다.
기능
Action Text
encrypted: true
옵션을 전달하여 Action Text 속성을 암호화할 수 있습니다.
class Message < ApplicationRecord has_rich_text :content, encrypted: true end
참고: Action Text 속성에 개별 암호화 옵션을 전달하는 것은 아직 지원되지 않습니다. 전역 암호화 옵션을 사용하여 비결정론적 암호화를 사용합니다.
픽스처
test.rb
에 다음 옵션을 추가하여 Rails 픽스처를 자동으로 암호화할 수 있습니다:
config.active_record.encryption.encrypt_fixtures = true
이 옵션이 활성화되면 모델에 정의된 암호화 가능한 모든 속성이 암호화 설정에 따라 암호화됩니다.
Action Text 픽스처
Action Text 픽스처를 암호화하려면 fixtures/action_text/encrypted_rich_texts.yml
에 배치해야 합니다.
지원되는 유형
active_record.encryption
은 기본 유형을 사용하여 값을 직렬화한 다음 암호화하지만, 사용자 지정 message_serializer
를 사용하지 않는 한 문자열로 직렬화할 수 있어야 합니다. serialized
와 같은 구조화된 유형은 기본적으로 지원됩니다.
사용자 지정 유형을 지원해야 하는 경우 직렬화된 속성을 사용하는 것이 권장되는 방법입니다. 직렬화된 속성 선언은 암호화 선언 전에 있어야 합니다:
# 올바른 방법 class Article < ApplicationRecord serialize :title, type: Title encrypts :title end # 잘못된 방법 class Article < ApplicationRecord encrypts :title serialize :title, type: Title end
대소문자 무시
결정론적으로 암호화된 데이터를 쿼리할 때 대소문자를 무시해야 할 수 있습니다. 이를 더 쉽게 수행할 수 있는 두 가지 접근 방식이 있습니다:
암호화된 속성을 선언할 때 :downcase
옵션을 사용하여 암호화 전에 내용을 소문자로 변환할 수 있네, 계속해서 번역하겠습니다.
class Person encrypts :email_address, deterministic: true, downcase: true end
:downcase
를 사용하면 원래 대소문자가 손실됩니다. 일부 상황에서는 쿼리 시에만 대소문자를 무시하고 원래 대소문자를 저장하고 싶을 수 있습니다. 이러한 상황에서는 :ignore_case
옵션을 사용할 수 있습니다. 이 경우 원본 대소문자를 저장하기 위해 original_<column_name>
이라는 새 열을 추가해야 합니다:
class Label encrypts :name, deterministic: true, ignore_case: true # 원래 대소문자가 `original_name` 열에 저장됩니다. end
암호화되지 않은 데이터 지원
암호화되지 않은 데이터의 마이그레이션을 용이하게 하기 위해 라이브러리에는 config.active_record.encryption.support_unencrypted_data
옵션이 포함되어 있습니다. true
로 설정하면:
- 암호화되지 않은 상태로 저장된 암호화된 속성을 읽으려고 할 때 오류가 발생하지 않습니다.
- 결정론적으로 암호화된 속성을 사용하는 쿼리에는 암호화되지 않은 “일반 텍스트” 버전이 포함됩니다. 이를 활성화하려면
config.active_record.encryption.extend_queries = true
를 설정해야 합니다.
이 옵션은 전환 기간 동안 사용하도록 의도되었습니다. 일반 데이터와 암호화된 데이터가 공존해야 합니다. 둘 다 기본적으로 false
로 설정되어 있으며, 이는 모든 애플리케이션에 대한 권장 목표입니다: 암호화되지 않은 데이터를 사용할 때 오류가 발생합니다.
이전 암호화 체계 지원
속성의 암호화 속성을 변경하면 기존 데이터가 손상될 수 있습니다. 예를 들어 결정론적 속성을 비결정론적으로 만들고 싶다고 가정해 보겠습니다. 모델에서 선언만 변경하면 기존 암호문을 읽을 수 없게 됩니다. 암호화 방법이 달라졌기 때문입니다.
이러한 상황을 지원하기 위해 이전 암호화 체계를 선언할 수 있습니다. 이는 두 가지 시나리오에서 사용됩니다:
- 암호화된 데이터를 읽을 때 Active Record 암호화는 현재 체계가 작동하지 않으면 이전 암호화 체계를 시도합니다.
- 결정론적 데이터를 쿼리할 때 이전 체계로 암호화된 암호문도 추가하여 다양한 체계로 암호화된 데이터와 원활하게 작동할 수 있습니다. 이를 활성화하려면
config.active_record.encryption.extend_queries = true
를 설정해야 합니다.
이전 암호화 체계는 다음과 같이 구성할 수 있습니다:
- 전역적으로
- 속성별로
전역 이전 암호화 체계
application.rb
에서 previous
구성 속성을 사용하여 이전 암호화 체계를 속성 목록으로 추가할 수 있습니다:
config.active_record.encryption.previous = [ { key_provider: MyOldKeyProvider.new } ]
속성별 암호화 체계
속성 선언에 :previous
를 사용합니다:
class Article encrypts :title, deterministic: true, previous: { deterministic: false } end
암호화 체계 및 결정론적 속성
이전 암호화 체계를 추가할 때:
- 비결정론적 암호화의 경우 새 정보는 항상 최신(현재) 암호화 체계로 암호화됩니다.
- 결정론적 암호화의 경우 새 정보는 기본적으로 가장 오래된 암호화 체계로 암호화됩니다.
일반적으로 결정론적 암호화에서는 암호문이 일정하게 유지되기를 원합니다. deterministic: { fixed: false }
를 설정하면 이 동작을 변경할 수 있습니다. 그러면 새 데이터 암호화에 최신 암호화 체계를 사용합니다.
고유 제약 조건
참고: 고유 제약 조건은 결정론적으로 암호화된 데이터에서만 사용할 수 있습니다.
고유 유효성 검사
확장된 쿼리가 활성화되어 있으면(config.active_record.encryption.extend_queries = true
) 고유 유효성 검사가 정상적으로 작동합니다.
class Person validates :email_address, uniqueness: true encrypts :email_address, deterministic: true, downcase: true end
암호화된 데이터와 암호화되지 않은 데이터를 결합하거나 이전 암호화 체계를 구성할 때도 작동합니다.
참고: 대소문자를 무시하려면 encrypts
선언에서 downcase:
또는 ignore_case:
를 사용해야 합니다. 유효성 검사에서 case_sensitive:
옵션을 사용하면 작동하지 않습니다.
고유 인덱스
결정론적으로 암호화된 열에 대한 고유 인덱스를 지원하려면 암호문이 절대 변경되지 않도록 해야 합니다.
이를 장려하기 위해 결정론적 속성은 여러 암호화 체계가 구성된 경우 기본적으로 가장 오래된 암호화 체계를 사용합니다. 그렇지 않으면 이러한 속성에 대한 암호화 속성이 변경되지 않도록 하는 것이 사용자의 책임입니다. 그렇지 않으면 고유 인덱스가 작동하지 않습니다.
class Person encrypts :email_address, deterministic: true end
암호화된 열 이름으로 명명된 매개변수 필터링
기본적으로 암호화된 열은 Rails 로그에서 자동으로 필터링되도록 구성됩니다. 이 동작을 비활성화하려면 application.rb
에 다음을 추가하세요:
config.active_record.encryption.add_to_filter_parameters = false
필터링이 활성화되어 있지만 특정 열을 자동 필터링에서 제외하려면 config.active_record.encryption.excluded_from_filter_parameters
에 추가하세요:
config.active_record.encryption.excluded_from_filter_parameters = [:catchphrase]
필터 매개변수를 생성할 때 Rails는 모델 이름을 접두사로 사용합니다. 예: Person#name
의 경우 필터 매개변수는 person.name
입니다.
인코딩
라이브러리는 비결정론적으로 암호화된 문자열 값의 인코딩을 유지합니다.
인코딩은 암호화된 페이로드와 함께 저장되므로 결정론적으로 암호화된 값은 기본적으로 UTF-8 인코딩을 강제합니다. 따라서 다른 인코딩을 가진 동일한 값은 암호화될 때 다른 암호문이 됩니다. 일반적으로 쿼리와 고유성 제약 조건이 작동하도록 유지하려는 것이 좋으므로 라이브러리가 이를 자동으로 변환합니다.
결정론적 암호화에 대한 기본 인코딩을 다음과 같이 구성할 수 있습니다:
config.active_record.encryption.forced_encoding_for_deterministic_encryption = Encoding::US_ASCII
그리고 이 동작을 비활성화하고 모든 경우에 인코딩을 유지하려면 다음과 같이 설정할 수 있습니다:
config.active_record.encryption.forced_encoding_for_deterministic_encryption = nil
키 관리
키 공급자는 키 관리 전략을 구현합니다. 전역적으로 또는 속성별로 키 공급자를 구성할 수 있습니다.
내장 키 공급자
DerivedSecretKeyProvider
제공된 비밀번호를 사용하여 PBKDF2를 통해 키를 제공하는 키 공급자입니다.
config.active_record.encryption.key_provider = ActiveRecord::Encryption::DerivedSecretKeyProvider.new(["some passwords", "to derive keys from. ", "These should be in", "credentials"])
참고: 기본적으로 active_record.encryption
은 active_record.encryption.primary_key
에 정의된 키를 사용하는 DerivedSecretKeyProvider
를 구성합니다.
EnvelopeEncryptionKeyProvider
엔벨로프 암호화 전략을 구현합니다:
- 각 데이터 암호화 작업에 대해 랜덤 키를 생성합니다.
- 자격 증명
active_record.encryption.primary_key
에 정의된 기본 키로 암호화된 데이터 키를 데이터 자체와 함께 저장합니다.
application.rb
에 다음을 추가하여 Active Record가 이 키 공급자를 사용하도록 구성할 수 있습니다:
config.active_record.encryption.key_provider = ActiveRecord::Encryption::EnvelopeEncryptionKeyProvider.new
다른 내장 키 공급자와 마찬가지로 active_record.encryption.primary_key
에 기본 키 목록을 제공하여 키 교체 체계를 구현할 수 있습니다.
사용자 지정 키 공급자
더 복잡한 키 관리 체계의 경우 초기화기에서 사용자 지정 키 공급자를 구성할 수 있습니다:
ActiveRecord::Encryption.key_provider = MyKeyProvider.new
키 공급자는 다음 인터페이스를 구현해야 합니다:
class MyKeyProvider def encryption_key end def decryption_keys(encrypted_message) end end
두 메서드 모두 ActiveRecord::Encryption::Key
객체를 반환합니다:
encryption_key
는 일부 내용을 암호화하는 데 사용되는 키를 반환합니다.decryption keys
는 주어진 메시지를 복호화할 수 있는 잠재적 키 목록을 반환합니다.
키에는 암호화된 메시지와 함께 저장되는 임의의 태그가 포함될 수 있습니다. ActiveRecord::Encryption::Message#headers
를 사용하여 복호화할 때 이러한 값을 검사할 수 있습니다.
모델별 키 공급자
:key_provider
옵션을 사용하여 클래스별로 키 공급자를 구성할 수 있습니다:
class Article < ApplicationRecord encrypts :summary, key_provider: ArticleKeyProvider.new end
모델별 키
:key
옵션을 사용하여 클래스별로 특정 키를 구성할 수 있습니다:
class Article < ApplicationRecord encrypts :summary, key: "some secret key for article summaries" end
Active Record는 이 키를 사용하여 데이터를 암호화하고 복호화하는 데 사용되는 키를 파생시킵니다.
키 교체
active_record.encryption
은 키 교체 체계를 구현하기 위해 키 목록으로 작동할 수 있습니다:
- 마지막 키가 새 내용을 암호화하는 데 사용됩니다.
- 하나라도 작동할 때까지 모든 키가 암호화된 내용을 복호화하는 데 시도됩니다.
active_record_encryption: primary_key: - a1cc4d7b9f420e40a337b9e68c5ecec6 # 이전 키는 기존 내용을 계속 복호화할 수 있습니다. - bc17e7b413fd4720716a7633027f8cc4 # 활성, 새 내용을 암호화합니다.네, 계속해서 번역하겠습니다. ```yml key_derivation_salt: a3226b97b3b2f8372d1fc6d497a0c0d3
이를 통해 새 키를 추가하고, 내용을 다시 암호화하고, 오래된 키를 삭제하는 워크플로를 통해 짧은 키 목록을 유지할 수 있습니다.
참고: 키 교체는 현재 결정론적 암호화에 지원되지 않습니다.
참고: Active Record 암호화는 아직 키 교체 프로세스의 자동 관리를 제공하지 않습니다. 모든 구성 요소가 있지만 아직 구현되지 않았습니다.
키 참조 저장
config.active_record.encryption.store_key_references
를 구성하여 active_record.encryption
이 암호화된 메시지에 암호화 키에 대한 참조를 저장하도록 할 수 있습니다.
config.active_record.encryption.store_key_references = true
이렇게 하면 시스템이 키 목록을 직접 찾을 수 있어 복호화 성능이 향상됩니다. 대신 저장 공간이 약간 늘어납니다.
API
기본 API
Active Record 암호화는 선언적으로 사용하도록 의도되었지만 고급 사용 시나리오를 위한 API를 제공합니다.
암호화 및 복호화
article.encrypt # 모든 암호화 가능한 속성 암호화 또는 재암호화 article.decrypt # 모든 암호화 가능한 속성 복호화
암호문 읽기
article.ciphertext_for(:title)
속성이 암호화되었는지 여부 확인
article.encrypted_attribute?(:title)
구성
구성 옵션
application.rb
(가장 일반적인 시나리오) 또는 특정 환경 구성 파일 config/environments/<env name>.rb
에서 Active Record 암호화 옵션을 구성할 수 있습니다(환경별로 설정하려는 경우).
경고: Rails 내장 자격 증명 지원을 사용하여 키를 저장하는 것이 좋습니다. 수동으로 구성 속성을 통해 설정하려는 경우 코드와 함께 커밋하지 않도록 주의하세요(예: 환경 변수 사용).
config.active_record.encryption.support_unencrypted_data
true이면 암호화되지 않은 데이터를 정상적으로 읽을 수 있습니다. false이면 오류가 발생합니다. 기본값: false
.
config.active_record.encryption.extend_queries
true이면 결정론적으로 암호화된 속성을 참조하는 쿼리가 필요한 경우 추가 값을 포함하도록 수정됩니다. 이러한 추가 값에는 값의 일반 버전(config.active_record.encryption.support_unencrypted_data
가 true인 경우) 및 이전 암호화 체계로 암호화된 값(제공된 경우 previous:
옵션)이 포함됩니다. 기본값: false
(실험적).
config.active_record.encryption.encrypt_fixtures
true이면 픽스처의 암호화 가능한 속성이 자동으로 암호화됩니다. 기본값: false
.
config.active_record.encryption.store_key_references
true이면 암호화된 메시지의 헤더에 암호화 키에 대한 참조가 저장됩니다. 이렇게 하면 여러 키를 사용할 때 복호화 속도가 빨라집니다. 기본값: false
.
config.active_record.encryption.add_to_filter_parameters
true이면 암호화된 속성 이름이 자동으로 config.filter_parameters
에 추가되어 로그에 표시되지 않습니다. 기본값: true
.
config.active_record.encryption.excluded_from_filter_parameters
config.active_record.encryption.add_to_filter_parameters
가 true일 때 필터링되지 않도록 할 매개변수 목록을 구성할 수 있습니다. 기본값: []
.
config.active_record.encryption.validate_column_size
열 크기를 기반으로 유효성 검사를 추가합니다. 이렇게 하면 압축이 잘되는 페이로드를 사용하여 큰 값을 저장하는 것을 방지할 수 있습니다. 기본값: true
.
config.active_record.encryption.primary_key
루트 데이터 암호화 키를 파생하는 데 사용되는 키 또는 키 목록입니다. 이는 active_record_encryption.primary_key
자격 증명을 통해 구성하는 것이 좋습니다.
config.active_record.encryption.deterministic_key
결정론적 암호화에 사용되는 키 또는 키 목록입니다. active_record_encryption.deterministic_key
자격 증명을 통해 구성하는 것이 좋습니다.
config.active_record.encryption.key_derivation_salt
키를 파생할 때 사용되는 솔트입니다. active_record_encryption.key_derivation_salt
자격 증명을 통해 구성하는 것이 좋습니다.
config.active_record.encryption.forced_encoding_for_deterministic_encryption
결정론적으로 암호화된 속성에 대한 기본 인코딩입니다. nil
로 설정하면 강제 인코딩이 비활성화됩니다. 기본값은 Encoding::UTF_8
입니다.
config.active_record.encryption.hash_digest_class
키를 파생하는 데 사용되는 다이제스트 알고리즘입니다. 기본값은 OpenSSL::Digest::SHA256
입니다.
config.active_record.encryption.support_sha1_for_non_deterministic_encryption
SHA1 다이제스트 클래스를 사용하여 비결정론적으로 암호화된 데이터를 복호화할 수 있습니다. 기본값은 false이며, 이는 config.active_record.encryption.hash_digest_class
에 구성된 다이제스트 알고리즘만 지원한다는 의미입니다.
암호화 컨텍스트
암호화 컨텍스트는 특정 시점에 사용되는 암호화 구성 요소를 정의합니다. 전역 구성을 기반으로 기본 암호화 컨텍스트가 있지만 특정 속성 또는 특정 코드 블록에 대해 사용자 지정 컨텍스트를 구성할 수 있습니다.
참고: 암호화 컨텍스트는 유연하지만 고급 구성 메커니즘입니다. 대부분의 사용자는 이에 대해 신경 쓰지 않아도 됩니다.
암호화 컨텍스트의 주요 구성 요소는 다음과 같습니다:
encryptor
: 데이터를 암호화하고 복호화하는 내부 API를 노출합니다.key_provider
와 상호 작용하여 암호화된 메시지를 구축하고 직렬화를 처리합니다. 암호화/복호화 자체는cipher
에 의해 수행되고 직렬화는message_serializer
에 의해 수행됩니다.cipher
: 실제 암호화 알고리즘(AES 256 GCM)key_provider
: 암호화 및 복호화 키를 제공합니다.message_serializer
: 암호화된 페이로드(Message
)를 직렬화하고 역직렬화합니다.
참고: 사용자 지정 message_serializer
를 빌드하는 경우 임의의 객체를 역직렬화할 수 없는 안전한 메커니즘을 사용해야 합니다. 일반적으로 지원되는 시나리오는 기존 암호화되지 않은 데이터 암호화입니다. 공격자는 이를 악용하여 암호화 전에 조작된 페이로드를 입력하고 RCE 공격을 수행할 수 있습니다. 따라서 사용자 지정 직렬화기는 Marshal
, YAML.load
(대신 YAML.safe_load
사용), JSON.load
(대신 JSON.parse
사용)를 피해야 합니다.
전역 암호화 컨텍스트
전역 암호화 컨텍스트는 기본적으로 사용되는 것이며 application.rb
또는 환경 구성 파일에서 다른 구성 속성과 마찬가지로 구성됩니다.
config.active_record.encryption.key_provider = ActiveRecord::Encryption::EnvelopeEncryptionKeyProvider.new config.active_record.encryption.encryptor = MyEncryptor.new
속성별 암호화 컨텍스트
속성 선언에서 암호화 컨텍스트 매개변수를 재정의할 수 있습니다:
class Attribute encrypts :title, encryptor: MyAttributeEncryptor.new end
코드 블록 실행 시 암호화 컨텍스트
ActiveRecord::Encryption.with_encryption_context
를 사용하여 특정 코드 블록에 대한 암호화 컨텍스트를 설정할 수 있습니다:
ActiveRecord::Encryption.with_encryption_context(encryptor: ActiveRecord::Encryption::NullEncryptor.new) do # ... end
내장 암호화 컨텍스트
암호화 비활성화
암호화 없이 코드를 실행할 수 있습니다:
ActiveRecord::Encryption.without_encryption do # ... end
이는 암호화된 텍스트를 읽으면 암호문이 반환되고 저장된 내용은 암호화되지 않음을 의미합니다.
암호화된 데이터 보호
암호화된 데이터는 보호하지만 암호화 없이 코드를 실행할 수 있습니다:
ActiveRecord::Encryption.protecting_encrypted_data do # ... end
이는 Rails 콘솔에서 암호화된 데이터를 보호하면서 임의의 코드를 실행할 수 있는 경우에 유용할 수 있습니다.