# DuckDB의 저장 데이터 암호화 기능

> Clean Markdown view of GeekNews topic #24526. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24526](https://news.hada.io/topic?id=24526)
- GeekNews Markdown: [https://news.hada.io/topic/24526.md](https://news.hada.io/topic/24526.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-11-22T08:36:54+09:00
- Updated: 2025-11-22T08:36:54+09:00
- Original source: [duckdb.org](https://duckdb.org/2025/11/19/encryption-in-duckdb)
- Points: 1
- Comments: 1

## Topic Body

- DuckDB 1.4 버전부터 **저장 데이터 암호화(Data-at-Rest Encryption)** 기능이 추가되어, 데이터베이스 파일 전체를 **AES 기반 표준 암호화**로 보호 가능  
- 지원 알고리듬은 **AES-GCM-256**과 **AES-CTR-256**, 이 중 GCM은 데이터 무결성 검증을 위한 **인증 태그(tag)** 를 포함  
- 암호화는 **데이터베이스 파일, WAL(Write-Ahead Log), 임시 파일** 모두에 적용되며, 키 관리와 메모리 보호를 위한 **보안 캐시 구조**를 포함  
- **OpenSSL**과 **Mbed TLS** 두 가지 구현이 제공되며, OpenSSL 사용 시 **하드웨어 가속**으로 성능 저하가 거의 없음  
- 암호화된 DuckDB 파일은 **보안성과 이식성**을 동시에 확보하며, 클라우드나 CDN 환경에서도 안전한 데이터 배포 가능  

---

### 암호화 개요
- DuckDB 1.4부터 데이터베이스 파일 전체를 **투명하게 암호화(Transparent Encryption)** 가능  
  - 저장 시 AES-GCM-256 또는 AES-CTR-256 암호화 사용  
  - AES-GCM은 무결성 검증을 위한 태그를 계산하며, AES-CTR은 더 빠르지만 인증 기능이 없음  
- AES는 **대칭키 암호화 알고리듬**으로, 동일한 키로 암호화와 복호화를 수행  
- IV(Initialization Vector)와 nonce를 사용해 동일 평문이 다른 암호문으로 변환되도록 보장  
- NIST 표준 요건은 아직 완전히 충족하지 않음  

### DuckDB 내부 구현 구조
- 데이터베이스 파일의 **메인 헤더**는 평문으로 유지되며, 암호화 여부를 나타내는 플래그와 **암호화 메타데이터** 저장  
  - 메타데이터에는 데이터베이스 식별자(salt), 암호화 알고리듬 정보, 암호화된 canary 포함  
- **키 파생 함수(KDF)** 를 통해 사용자 입력 키를 32바이트 보안 키로 변환  
  - 파생된 키는 **보안 캐시**에 저장되어 디스크로 스왑되지 않음  
  - 원본 키는 메모리에서 즉시 삭제  
- 데이터 블록은 기본 256KB 단위로 저장되며, 암호화 시 블록 헤더에 **nonce/IV**와 **태그**가 추가되어 40바이트로 확장  
  - 체크섬은 암호화되어 저장  

### WAL(Write-Ahead Log) 암호화
- WAL은 트랜잭션 복구용 로그 파일로, DuckDB에서는 **항목 단위로 암호화** 수행  
  - 각 항목에 nonce와 태그를 추가하여 AES-GCM 방식으로 보호  
  - 암호화된 WAL 항목은 길이(평문) → nonce → 암호화된 체크섬 및 데이터 → 태그 순으로 구성  
- 암호화 키가 지정된 데이터베이스에서는 WAL 암호화가 **자동 활성화**  

### 임시 파일 암호화
- 정렬, 조인, 윈도 함수 등 대용량 연산 시 생성되는 **임시 파일**도 자동 암호화  
  - 암호화된 데이터베이스를 연결하거나 `SET temp_file_encryption = true` 설정 시 활성화  
  - DuckDB가 내부적으로 **임시 키**를 생성하며, 충돌 시 복호화 불가  
- 임시 파일은 `.tmp` 또는 `.block` 확장자를 가지며, 크기 정보가 헤더에 포함  
  - 체크섬은 계산 비용 절감을 위해 생략  

### 암호화 사용 방법
- 세 가지 방식 지원:  
  1. 기존 데이터베이스 암호화  
  2. 새 암호화 데이터베이스 생성  
  3. 기존 암호화 데이터베이스 재암호화  
- 예시 명령:
  ```
  ATTACH 'encrypted.duckdb' AS encrypted (ENCRYPTION_KEY 'asdf');
  COPY FROM DATABASE unencrypted TO encrypted;
  ```
- 암호화 여부는 `FROM duckdb_databases();` 명령으로 확인 가능  
- 기본 암호화 알고리듬은 **AES-GCM**, 필요 시 **AES-CTR**로 지정 가능  
- 암호화된 데이터는 **엔트로피(Entropy)** 가 높아 무작위 데이터처럼 보임  

### 구현 및 성능
- DuckDB는 외부 의존성을 최소화하기 위해 **Mbed TLS**와 **OpenSSL** 두 가지 암호화 구현을 포함  
  - Mbed TLS는 하드웨어 가속 비활성화로 성능이 낮고, 난수 생성기 취약점 발견으로 **쓰기 기능 비활성화(1.4.1 이후)**  
  - OpenSSL은 **하드웨어 가속 및 안전한 난수 생성기**를 사용, `httpfs` 확장 로드 시 자동 전환  
- 성능 테스트 결과:  
  - 비암호화 SUMMARIZE 쿼리: 5.4초  
  - Mbed TLS 암호화: 6.2초  
  - OpenSSL 암호화: 5.4초 (성능 저하 없음)  
- TPC-H Power/Throughput 테스트에서도 암호화 사용 시 **성능 차이 미미**  
  - Power@Size: 624,296 → 571,985  
  - Throughput@Size: 450,409 → 145,353 (디스크 I/O 증가 시 약간 감소)  

### 결론
- DuckDB의 **저장 데이터 암호화 기능**으로 데이터베이스 파일 전체를 안전하게 보호 가능  
- **WAL과 임시 파일까지 암호화**되어 클라우드 환경에서도 데이터 유출 위험 감소  
- **OpenSSL 기반 구현 시 성능 손실 거의 없음**, 실무 환경에서도 효율적 사용 가능  
- 암호화된 DuckDB 파일은 **CDN 등 외부 배포**에도 적합하며, 다중 테이블 저장 등 기존 기능 유지  
- DuckDB 팀은 향후 사용자 피드백을 통해 기능 개선 예정

## Comments



### Comment 46666

- Author: neo
- Created: 2025-11-22T08:36:56+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=45996585) 
- AES-GCM의 **nonce 재사용** 민감도는 구현 시 까다로운 부분임  
  문서에서는 이를 인지하고 있지만 해결 방법을 공유하지 않았음  
  헤더에 12바이트 대신 16바이트 nonce가 포함되어 있고, 어떤 바이트가 랜덤인지 명시되지 않아 혼란스러움. 혹시 내가 놓친 부분이 있는지 궁금함
  - 정적 키를 사용하고, 12바이트 **랜덤 nonce**를 생성하며, 임시 버퍼에는 세션별 키를 사용하지 않는 구조임

- DuckDB 팀의 성과에 계속 놀라고 있음  
  예전에 OpenSSL로 DuckDB 파일을 암호화하는 단순한 솔루션을 만들었는데, 첫 쿼리 시 **2배의 실행 시간**이 걸리고 메모리도 많이 사용했음  
  반면 DuckDB는 페이지 단위 암호화와 CPU의 AES 가속을 활용해 읽기/쓰기 비용이 거의 없는 수준임
  - 왜 그냥 **LUKS**를 쓰지 않는지 궁금함  
    커널 레벨에서 가속을 활용하고, 상위 애플리케이션에는 투명하게 동작함  
    여러 앱이 각기 다른 ACL과 키를 써야 하는 경우가 아니라면 DB 자체 암호화는 불필요함
  - 솔직히 말해 DuckDB의 작업이 “놀라운” 수준은 아니라고 생각함  
    단순한 전체 파일 암호화 방식과 비교하면 당연히 좋아 보이지만, 이는 **기본적인 수준의 구현**임  
    우리 스스로도 이런 수준의 품질을 목표로 해야 함
  - 결국 **파이프라이닝** 덕분임  
    저장소 입출력에 비하면 암호화 비용은 거의 무료에 가까움

- MotherDuck 외에 다중 사용자용 **클라우드 기반 DuckDB**를 잘 운영하는 모델이 있는지 궁금함  
  일반 DB처럼 여러 사용자가 동시에 접근하면서 DuckDB의 장점을 그대로 활용할 수 있는 구조를 찾고 있음
  - 순수 DuckDB만 쓴다면 [Arrow Flight 서버](https://www.definite.app/blog/duck-takes-flight)를 앞단에 두거나 [httpserver 확장](https://github.com/Query-farm/httpserver)을 사용할 수 있음  
    `.duckdb` 파일을 어디에 저장하느냐(S3 vs EFS)에 따라 성능 차이가 큼  
    하지만 **DuckLake**가 더 나은 멀티플레이어 옵션으로 보임  
    우리는 [DuckLake](https://www.definite.app/)를 제품에 사용 중이며, 성능 저하를 줄이기 위해 분석용 테이블은 GCP Filestore 같은 빠른 스토리지에 저장함  
    하나의 DuckLake 카탈로그 안에서도 여러 스토리지 방식을 혼합할 수 있어 유연함
  - 요즘 “**Postgres 안의 DuckDB**”라는 글을 자주 보는데, 아마 그게 원하는 형태일 것 같음
  - [GizmoSQL](https://github.com/gizmodata/gizmosql)도 참고할 만함

- DuckDB는 지금까지 써본 **AI 도구들보다 더 유용**했음  
  LLM을 좋아하지만, 실제 업무 효율에서는 DuckDB가 훨씬 큰 도움을 줌

- 키의 **인덱싱 처리 방식**이 궁금함  
  검색 시 키를 암호화한 상태로 찾는지, 아니면 블록마다 복호화를 수행하는지 알고 싶음

- “SQLite 암호화 확장은 2000달러 유료 애드온”이라는 말이 있지만,  
  [SQLiteMultipleCiphers](https://utelle.github.io/SQLite3MultipleCiphers/)는 오래전부터 무료로 제공되고 있음  
  또한 [Turso Database](https://docs.turso.tech/tursodb/encryption)는 기본적으로 암호화를 지원함
  - 실제로 Python이나 Go에서 이런 변형된 SQLite를 **플러그인과 함께 빌드**해 사용하는 방법이 궁금함  
    언어별로 링크 과정이 까다로워 보임
  - [SQLCipher](https://github.com/sqlcipher/sqlcipher)도 있음  
    2009년부터 개발되어 안정적으로 동작하는 솔루션임
