암호화
암호화 (Encryption)
아이스버그 테이블 암호화는 신뢰할 수 없는 스토리지에서 테이블 데이터의 기밀성과 무결성을 보호해요. 이 문서에서는 테이블 암호화를 활성화하는 방법과 카탈로그 보안 요구사항, KMS 클라이언트, 그리고 내부 동작 원리를 설명해드릴게요. 데이터·삭제·매니페스트·매니페스트 리스트 파일이 스토리지 백엔드로 보내지기 전에 암호화되고 변조 방지(tamper-proof) 처리돼요.
출처: 문서
본문
아이스버그 테이블 암호화는 신뢰할 수 없는 스토리지에서 테이블 데이터의 기밀성과 무결성을 보호해요. 데이터, 삭제(delete), 매니페스트, 매니페스트 리스트 파일은 스토리지 백엔드로 보내지기 전에 암호화되고 변조 방지 처리돼요.
metadata.json 파일은 데이터나 통계를 포함하지 않기 때문에 암호화되지 않아요.
현재 암호화는 Parquet과 Avro 데이터 포맷을 가진 테이블에 대해 Hive와 REST 카탈로그에서 지원돼요.
테이블 암호화를 활성화하려면 두 개의 파라미터가 필요해요.
- KMS(키 관리 서비스)를 지정하는 카탈로그 속성. 미리 정의된 KMS 클라이언트용 encryption.kms-type (aws, azure 또는 gcp)이거나, 커스텀 KMS 클라이언트용 클라이언트 클래스 경로를 지정하는 encryption.kms-impl이에요.
- 테이블을 암호화·복호화하는 데 사용되는 마스터 키의 ID를 지정하는 테이블 속성 encryption.key-id. 마스터 키는 KMS에 저장되고 관리돼요.
테이블 암호화에 대한 자세한 내용은 "부록: 내부 구조 개요 (Appendix: Internals Overview)" 하위 섹션을 참고해주세요.
예시 (Example)
spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:1.11.0\
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog \
--conf spark.sql.catalog.spark_catalog.type=hive \
--conf spark.sql.catalog.local=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.local.type=hive \
--conf spark.sql.catalog.local.encryption.kms-type=aws
CREATE TABLE local.db.table (id bigint, data string) USING iceberg
TBLPROPERTIES ('encryption.key-id'='<master-key-id>');
삽입된 데이터는 자동으로 암호화돼요.
INSERT INTO local.db.table VALUES (1, 'a'), (2, 'b'), (3, 'c');
암호화를 검증하려면 데이터, 매니페스트, 매니페스트 리스트 파일의 내용을 명령줄에서 다음으로 덤프할 수 있어요.
hexdump -C <path/to/file> | more
Parquet 파일은 "PARE" 매직 문자열(PARquet Encrypted footer 모드)로 시작해야 하고, 매니페스트/리스트 파일은 "AGS1" 매직 문자열(Aes Gcm Stream version 1)로 시작해야 해요.
조회된 데이터는 자동으로 복호화돼요.
SELECT * FROM local.db.table;
카탈로그 보안 요구사항 (Catalog security requirements)
- 카탈로그는 encryption.key-id 속성이 테이블 수명 동안 수정되거나 제거되지 않도록 보장해야 해요.
- 제대로 동작하려면, 아이스버그 테이블 암호화는 metadata.json 파일이 변조에 취약한 스토리지에 보호되지 않은 채 보관된다면 카탈로그 구현이 metadata.json 파일에서 메타데이터를 직접 가져오지 않도록 요구해요. 카탈로그는: 신뢰할 수 있는 독립 객체 스토리지에 메타데이터를 보관할 수 있어요. 변조 방지 스토리지에서 metadata.json 파일을 사용할 수 있어요. 변조에 취약한 스토리지에서 metadata.json 파일의 무결성을 검증하는 체크섬 기술을 사용할 수 있어요 (체크섬은 별도의 신뢰할 수 있는 스토리지에 보관해야 해요).
키 관리 클라이언트 (Key Management Clients)
현재 아이스버그는 AWS, GCP, Azure KMS 시스템을 위한 클라이언트를 갖고 있어요. org.apache.iceberg.encryption.KeyManagementClient 인터페이스를 구현하면 다른 키 관리 시스템을 위한 커스텀 클라이언트를 만들 수 있어요.
이 인터페이스에는 다음과 같은 주요 메서드가 있어요.
/**
* Initialize the KMS client with given properties.
*
* @param properties kms client properties (taken from catalog properties)
*/
void initialize(Map<String, String> properties);
/**
* Wrap a secret key, using a wrapping/master key which is stored in KMS and referenced by an ID.
* Wrapping means encryption of the secret key with the master key, and adding optional
* KMS-specific metadata that allows the KMS to decrypt the secret key in an unwrapping call.
*
* @param key a secret key being wrapped
* @param wrappingKeyId a key ID that represents a wrapping key stored in KMS
* @return wrapped key material
*/
ByteBuffer wrapKey(ByteBuffer key, String wrappingKeyId);
/**
* Unwrap a secret key, using a wrapping/master key which is stored in KMS and referenced by an
* ID.
*
* @param wrappedKey wrapped key material (encrypted key and optional KMS metadata, returned by
* the wrapKey method)
* @param wrappingKeyId a key ID that represents a wrapping key stored in KMS
* @return raw key bytes
*/
ByteBuffer unwrapKey(ByteBuffer wrappedKey, String wrappingKeyId);
부록: 내부 구조 개요 (Appendix: Internals Overview)
표준 아이스버그 암호화 관리자는 각 데이터 및 삭제 파일에 대해 암호화 키와 고유 파일 ID("AAD 프리픽스")를 생성해요. 이 생성은 워커 노드에서 보안 난수 생성기(secure random number generator)를 사용해 수행돼요. Parquet 데이터 파일의 경우 이 파라미터들이 네이티브 Parquet Modular Encryption 메커니즘에 전달돼요. Avro 데이터 파일의 경우 AES GCM Stream 암호화 메커니즘에 전달돼요.
부모 매니페스트 파일은 각 데이터 및 삭제 파일의 암호화 키와 AAD 프리픽스를 key_metadata 필드에 저장해요. Avro 데이터 테이블의 경우 데이터 파일 길이도 key_metadata에 추가돼요. 매니페스트 파일은 표준 암호화 관리자가 생성한 암호화 키와 AAD 프리픽스를 사용해 AES GCM Stream 암호화 메커니즘으로 암호화돼요. 이 생성은 드라이버 노드에서 보안 난수 생성기를 사용해 수행돼요.
부모 매니페스트 리스트 파일은 각 매니페스트 파일의 암호화 키, AAD 프리픽스, 파일 길이를 key_metadata 필드에 저장해요. 매니페스트 리스트 파일은 표준 암호화 관리자가 생성한 암호화 키와 AAD 프리픽스를 사용해 AES GCM Stream 암호화 메커니즘으로 암호화돼요.
매니페스트 리스트 암호화 키, AAD 프리픽스, 파일 길이는 키 메타데이터(key metadata) 객체에 담겨요. 이 객체는 직렬화된 뒤 "키 암호화 키"(KEK)로 암호화되고, KEK 생성 타임스탬프를 AES GCM AAD로 사용해요. KEK와 고유한 KEK_ID는 보안 난수 생성기를 사용해 생성돼요. 각 스냅샷에 대해 매니페스트 리스트 키 메타데이터를 암호화하는 암호화 키의 KEK_ID가 테이블 메타데이터 스냅샷 구조의 key-id 필드에 보관돼요. 암호화된 매니페스트 리스트 키 메타데이터는 테이블 메타데이터 구조의 encryption-keys 목록에 보관돼요.
KEK는 KMS 클라이언트를 통해 테이블 마스터 키로 암호화돼요. 결과는 테이블 메타데이터 구조의 encryption-keys 목록에 보관돼요. KEK는 NIST SP 800-57 사양이 허용하는 기간 동안 재사용돼요. 그런 다음 회전(rotate)되는데, 새 매니페스트 리스트 키 메타데이터 객체의 암호화를 위해 새 KEK와 KEK_ID가 생성돼요. 새 KEK는 테이블 마스터 키로 암호화되어 encryption-keys 목록에 저장돼요. 이전 KEK들은 기존 테이블 스냅샷을 위해 보관돼요.