Loading the catalog…
Loading the catalog…
『Real MySQL 8.0』 7장을 읽고, 핵심 개념을 쉽게 이해할 수 있도록 제 방식대로 정리한 글입니다. 📌 들어가기 전에 왜 데이터를 암호화할까? 개인정보, 결제 정보 같은 민감한 데이터 를 보호하기 위해서입니다. 서버의 디스크나 백업 파일이 유출되더라도, 암호화 키가 없으면 내용을 읽을 수 없게 만드는 것이 목적입니다. MySQL 8.0 암호화 대상 한눈에 보기 암호화 대상 설정 다루는 절 테이블(데이터 파일) ENCRYPTION = 'Y' 7.3 언두 로그 / 리두 로그 innodb_undo_log_encrypt , innodb_redo_log_encrypt 7.4 바이너리 로그 / 릴레이 로그 binlog_encryption 7.5 💡 테이블만 암호화하고 로그를 암호화하지 않으면, 로그 파일에 데이터가 평문으로 남을 수 있습니다. 그래서 실제로는 세 가지를 함께 고려해야 합니다. 7.1 MySQL 서버의 데이터 암호화 TDE (Transparent Data Encryption) MySQL의 데이터 암호화는 디스크에 쓰고 읽는 시점 에 동작합니다. [쓰기] 버퍼 풀 (평문) ──암호화──▶ 디스크 (암호문) [읽기] 디스크 (암호문) ──복호화──▶ 버퍼 풀 (평문) MySQL 서버의 다른 부분(쿼리 처리 등)은 데이터가 암호화됐는지 전혀 신경 쓰지 않습니다. 사용자 입장에서도 일반 테이블과 똑같이 사용합니다. 그래서 이 방식을 투명한 데이터 암호화(TDE, Transparent Data Encryption) 라고 부릅니다. 디스크에 저장된 상태의 데이터를 보호한다는 의미로 Data at Rest Encryption 이라고도 합니다. 에디션별 키 관리 방식 (키링 플러그인) 암호화 키는 키링(Keyring) 플러그인 을 통해 관리합니다. 에디션 사용 가능한 키링 커뮤니티 keyring_file (마스터 키를 디스크 파일 에 저장) 엔터프라이즈 keyring_file , keyring_encrypted_file , keyring_okv , keyring_aws 등 (외부 키 관리 서버 연동 가능) 7.1.1 2단계 키 관리 MySQL은 키를 두 단계 로 나눠서 관리합니다. ┌──────────── 키링 (외부 파일 / 키 관리 서버) ────────────┐ │ 🔑 마스터 키 (Master Key) │ └───────────────────────┬──────────────────────────┘ │ 테이블스페이스 키를 암호화 ▼ ┌──────────── 각 테이블 데이터 파일 헤더 ─────────────────┐ │ 🔐 테이블스페이스 키 (Tablespace Key) │ │ (마스터 키로 암호화된 상태로 저장) │ └───────────────────────┬──────────────────────────┘ │ 실제 데이터를 암호화 ▼ ┌──────────── 데이터 파일 ─────────────────────────────┐ │ 📄 암호화된 데이터 │ └──────────────────────────────────────────────────┘ 키 저장 위치 역할 마스터 키 키링(외부 파일 또는 키 관리 서버) 테이블스페이스 키를 암호화 테이블스페이스 키 각 테이블 데이터 파일의 헤더 (마스터 키로 암호화된 상태) 실제 데이터를 암호화 🧩 비유 테이블스페이스 키 = 각 방(테이블)의 문을 여는 열쇠 마스터 키 = 그 방 열쇠들을 넣어둔 금고의 열쇠 금고 열쇠(마스터 키)는 건물 밖(키링)에 따로 보관 왜 2단계로 나눌까? → 마스터 키 변경이 빠르다 보안 정책상 키는 주기적으로 변경 해야 합니다. ALTER INSTANCE ROTATE INNODB MASTER KEY; 마스터 키 변경 시 1. 새로운 마스터 키 발급 2. 모든 테이블스페이스 키를 기존 마스터 키로 복호화 3. 새 마스터 키로 다시 암호화해서 데이터 파일 헤더에 저장 → 데이터 파일 전체를 다시 암호화할 필요 없음 ✅ 키를 하나만 쓴다면 2단계 키를 쓴다면 키를 바꿀 때마다 모든 데이터 파일을 다시 암호화 → 매우 오래 걸림 테이블스페이스 키만 다시 암호화 → 빠름 💡 테이블스페이스 키는 MySQL 서버 외부로 노출되지 않기 때문에 따로 변경할 필요가 없습니다. 암호화 알고리즘 대상 알고리즘 테이블스페이스 키 암호화 AES 256비트 (ECB 모드) 실제 데이터 암호화 AES 256비트 (CBC 모드) 7.1.2 암호화와 성능 언제 암호화·복호화가 일어날까? 작업 시점 사용자 응답에 영향 복호화 디스크에서 읽어 버퍼 풀에 올릴 때 한 번 디스크에서 읽어야 하는 경우 약간 느려짐 암호화 더티 페이지를 디스크에 기록할 때 백그라운드 스레드가 처리하므로 거의 없음 버퍼 풀에 이미 있는 데이터 → 이미 복호화된 상태 → 추가 비용 없음 ✅ 버퍼 풀에 없는 데이터 → 디스크에서 읽으며 복호화 → 약간의 지연 💡 데이터 대부분이 버퍼 풀에 올라와 있는 서버라면, 암호화로 인한 성능 영향은 크지 않습니다. 책의 테스트에서도 페이지 하나를 읽고 쓰는 시간은 몇 배 늘어났지만, 마이크로초 단위 라 체감은 크지 않은 수준이었습니다. 암호화 + 압축을 함께 쓴다면? 1 압축 먼저 → 2 그 다음 암호화 이유 설명 압축 효율 암호화된 데이터는 랜덤한 바이트처럼 보여서 거의 압축되지 않음 → 압축을 먼저 해야 효과가 있음 버퍼 풀 활용 버퍼 풀에는 압축만 된(암호화되지 않은) 페이지 가 올라오므로, 버퍼 풀 안에서는 복호화가 필요 없음 7.1.3 암호화와 복제 소스 서버와 레플리카는 각자의 마스터 키를 가진다 ┌─── 소스 서버 ───┐ ┌─── 레플리카 ───┐ │ 🔑 마스터 키 A │ ──복제──▶ │ 🔑 마스터 키 B │ │ 데이터: 동일 │ │ 데이터: 동일 │ │ 파일 내용: 다름 │ │ 파일 내용: 다름 │ └───────────────┘ └───────────────┘ 복제 소스와 레플리카는 서로 다른 마스터 키 를 사용합니다. 그래서 데이터 내용은 같아도, 암호화된 데이터 파일 내용은 서로 다릅니다. ALTER INSTANCE ROTATE INNODB MASTER KEY 명령이 레플리카로 복제되더라도, 레플리카는 자기만의 새로운 마스터 키 를 생성합니다. ⚠️ 백업 시 주의 주의점 설명 키링 파일도 백업 키링 파일이 없으면 백업한 데이터를 복구할 수 없음 분리 보관 키링 파일을 데이터 백업과 같은 곳에 두면 암호화한 의미가 없음 → 별도로 안전하게 보관 💡 TDE를 사용한다면, 데이터 백업 + 키링 파일 백업 을 함께 관리해야 합니다. 7.2 keyring_file 플러그인 설치 keyring_file 플러그인이란? MySQL 커뮤니티 에디션에서 사용할 수 있는 키링 플러그인입니다. 마스터 키를 디스크의 파일 에 저장합니다. ⚠️ 마스터 키가 평문 파일 로 저장되기 때문에, 파일이 유출되면 암호화가 무의미해집니다. 파일 위치와 접근 권한을 철저히 관리해야 합니다. 설치 방법 키링 플러그인은 다른 플러그인보다 먼저 초기화되어야 하므로, early-plugin-load 옵션으로 설정합니다. # my.cnf [mysqld] early-plugin-load = keyring_file.so keyring_file_data = /very/secure/directory/tde_master.key 설정 설명 early-plugin-load MySQL 서버가 시작될 때 가장 먼저 로드할 플러그인 keyring_file_data 마스터 키를 저장할 파일 경로 💡 하나의 MySQL 서버에서 여러 인스턴스를 실행한다면, 인스턴스마다 다른 키링 파일 경로 를 지정해야 합니다. 설치 확인 SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%'; +--------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +--------------+---------------+ | keyring_file | ACTIVE | +--------------+---------------+ 서버를 시작하면 키링 파일이 빈 파일 로 생성됩니다. 실제 마스터 키는 암호화된 테이블을 처음 생성하거나 마스터 키를 로테이션할 때 만들어집니다. 💡 참고로 MySQL 8.0.24부터는 키링 플러그인 대신 컴포넌트 ( component_keyring_file ) 사용이 권장됩니다. 7.3 테이블 암호화 7.3.1 테이블 생성 암호화 테이블 생성 CREATE TABLE tab_encrypted ( id INT, data VARCHAR(100), PRIMARY KEY (id) ) ENCRYPTION = 'Y'; INSERT INTO tab_encrypted VALUES (1, 'test_data'); SELECT * FROM tab_encrypted; -- 일반 테이블과 똑같이 조회됨 💡 사용자 입장에서는 ENCRYPTION = 'Y' 옵션만 추가하면 되고, 사용 방법은 일반 테이블과 같습니다. 암호화된 테이블 확인 SELECT table_schema, table_name, create_options FROM information_schema.tables WHERE create_options LIKE '%ENCRYPTION="Y"%'; 모든 테이블을 기본으로 암호화하려면? SET GLOBAL default_table_encryption = ON; 이 설정을 켜면 ENCRYPTION 옵션을 지정하지 않아도 새로 생성하는 테이블이 자동으로 암호화 됩니다. 7.3.2 응용 프로그램 암호화와의 비교 암호화는 MySQL(TDE)에서 할 수도 있고, 애플리케이션에서 직접 할 수도 있습니다. [응용 프로그램 암호화] 애플리케이션: '1990' ──암호화──▶ 'xK9#mQ2...' ──저장──▶ MySQL → MySQL은 'xK9#mQ2...'가 무슨 값인지 모름 [TDE] 애플리케이션: '1990' ──저장──▶ MySQL ──디스크 기록 시 암호화──▶ 디스크 → MySQL 내부에서는 '1990'으로 인식 응용 프로그램 암호화의 문제점 애플리케이션에서 암호화한 값은 MySQL 입장에서 의미 없는 문자열 이기 때문에 이런 쿼리를 쓸 수 없습니다. -- birth_year 컬럼을 애플리케이션에서 암호화했다면 -- ❌ 범위 검색 불가 SELECT * FROM app_user WHERE birth_year BETWEEN 2000 AND 2010; -- ❌ 정렬 불가 SELECT * FROM app_user ORDER BY birth_year LIMIT 10; 문제 설명 범위 검색 불가 암호화된 값은 크기 비교가 의미 없음 정렬 불가 암호문 순서 ≠ 원래 값 순서 인덱스 활용 제한 범위 조건이나 정렬에 인덱스를 쓸 수 없음 비교 항목 응용 프로그램 암호화 TDE (MySQL 암호화) 암호화 위치 애플리케이션 MySQL 서버 (디스크 I/O 시점) 범위 검색 / 정렬 ❌ ✅ 인덱스 활용 제한적 일반 테이블과 동일 SQL로 조회 시 암호문 으로 보임 (DB 관리자도 내용을 모름) 평문 으로 보임 ✅ 정리 검색·정렬이 필요한 컬럼 → TDE DB 관리자에게도 노출되면 안 되는 민감한 컬럼(주민번호, 카드번호 등) → 응용 프로그램 암호화 보안 요구사항에 따라 두 가지를 함께 적용 할 수도 있습니다. 7.3.3 테이블스페이스 이동 테이블스페이스 이동이란? 테이블 데이터를 덤프해서 다시 넣는 대신, 데이터 파일( .ibd ) 자체를 복사 해서 다른 서버로 옮기는 기능입니다. 💡 데이터가 많을 때 mysqldump 로 덤프·적재하는 것보다 훨씬 빠릅니다. 일반 테이블 이동 과정 -- [원본 서버] FLUSH TABLES source_table FOR EXPORT; -- → source_table.cfg 파일 생성 (테이블 구조 정보) -- → .ibd, .cfg 파일 복사 UNLOCK TABLES; 암호화된 테이블이라면? 암호화된 테이블은 원본 서버의 마스터 키 로 테이블스페이스 키가 암호화되어 있습니다. 다른 서버는 그 마스터 키를 모르기 때문에, 파일만 복사하면 복호화할 수 없습니다. 그래서 FLUSH TABLES ... FOR EXPORT 실행 시 파일이 하나 더 생성됩니다. 파일 내용 .ibd 실제 데이터 파일 .cfg 테이블 구조 정보 .cfp 임시 마스터 키 로 암호화한 테이블스페이스 키 [원본 서버] FLUSH TABLES source_table FOR EXPORT; → 임시 마스터 키 생성 → 테이블스페이스 키를 임시 마스터 키로 암호화해서 .cfp 파일에 저장 → .ibd, .cfg, .cfp 파일 복사 UNLOCK TABLES; [대상 서버] ALTER TABLE target_table DISCARD TABLESPACE; → 복사한 .ibd, .cfg, .cfp 파일을 데이터 디렉터리에 배치 ALTER TABLE target_table IMPORT TABLESPACE; → .cfp 파일로 테이블스페이스 키를 복호화 → 대상 서버의 마스터 키로 다시 암호화해서 저장 ✅ ⚠️ .cfp 파일을 빠뜨리면 복구할 수 없습니다. 암호화된 테이블을 이동할 때는 반드시 .cfp 파일까지 함께 복사해야 합니다. 7.4 언두 로그 및 리두 로그 암호화 문제: 테이블만 암호화하면 로그는 평문 테이블 데이터 파일 → 암호화 ✅ 리두 로그 / 언두 로그 → 평문 ❌ ← 여기에 데이터 변경 내용이 그대로 남음 테이블을 암호화해도, 리두 로그와 언두 로그 에는 데이터 변경 내용이 평문으로 기록될 수 있습니다. MySQL 8.0.16부터 리두 로그와 언두 로그도 암호화할 수 있습니다. 설정 SET GLOBAL innodb_undo_log_encrypt = ON; SET GLOBAL innodb_redo_log_encrypt = ON; -- 설정 확인 SHOW GLOBAL VARIABLES LIKE 'innodb_%_log_encrypt'; 동작 방식 상황 결과 암호화를 켜면 켠 시점 이후 에 기록되는 로그만 암호화. 이전 로그는 평문 그대로 암호화를 끄면 이후 로그는 평문. 이미 암호화된 로그는 암호화된 상태 그대로 유지 ⚠️ 암호화를 껐더라도 이전에 암호화된 로그가 남아 있다면, 복구할 때 암호화 키가 여전히 필요 합니다. 키 관리 🔑 마스터 키 └─ 🔐 리두 로그 / 언두 로그 전용 프라이빗 키 (로그 파일 헤더에 암호화되어 저장) └─ 📄 리두 로그 / 언두 로그 데이터 암호화 리두 로그와 언두 로그는 테이블스페이스 키가 아니라, 각각의 프라이빗 키 로 암호화됩니다. 이 프라이빗 키는 마스터 키로 암호화 되어 로그 파일의 헤더 에 저장됩니다. 7.5 바이너리 로그 암호화 문제: 바이너리 로그도 평문 바이너리 로그에는 데이터 변경 내용이 그대로 기록됩니다. 바이너리 로그는 복제나 시점 복구(PITR)를 위해 오랫동안 보관 하는 경우가 많아서, 유출 위험도 큽니다. MySQL 8.0.14부터 바이너리 로그를 암호화할 수 있습니다. SET GLOBAL binlog_encryption = ON; 💡 바이너리 로그뿐 아니라 레플리카의 릴레이 로그 도 함께 암호화됩니다. 7.5.1 바이너리 로그 암호화 키 관리 바이너리 로그도 2단계 키 관리 방식을 사용합니다. ┌──────────── 키링 ────────────────────────────┐ │ 🔑 바이너리 로그 암호화 키 │ ← 테이블 암호화의 "마스터 키" 역할 └───────────────────┬─────────────────────────┘ │ 파일 키를 암호화 ▼ ┌──────────── 각 바이너리 로그 / 릴레이 로그 파일 헤더 ──┐ │ 🔐 파일 키 (File Key) │ ← 파일마다 하나씩 └───────────────────┬─────────────────────────┘ │ 실제 로그 데이터를 암호화 ▼ 📄 암호화된 바이너리 로그 키 비교 대상 역할 바이너리 로그 암호화 키 테이블 암호화의 마스터 키 파일 키를 암호화 파일 키 테이블 암호화의 테이블스페이스 키 바이너리 로그 파일마다 하나씩 생성되어 로그 데이터를 암호화 7.5.2 바이너리 로그 암호화 키 변경 ALTER INSTANCE ROTATE BINLOG MASTER KEY; 키 변경 과정 1. 새로운 바이너리 로그 암호화 키를 발급해서 키링 파일에 저장 2. 바이너리 로그 파일과 릴레이 로그 파일을 새 파일로 전환(로테이션) 3. 새로 생성되는 로그 파일의 파일 키는 새 암호화 키로 암호화 4. 기존 바이너리 로그·릴레이 로그 파일의 파일 키를 읽어서 새 암호화 키로 다시 암호화 (암호화되지 않은 로그 파일은 무시) 5. 모든 파일의 변환이 끝나면, 기존 바이너리 로그 암호화 키를 키링 파일에서 삭제 ⚠️ 4번은 보관 중인 바이너리 로그 파일이 많으면 시간이 오래 걸릴 수 있습니다. 대신 로그 데이터 전체가 아니라 파일 키만 다시 암호화 하므로, 2단계 키 관리 덕분에 그나마 빠르게 처리됩니다. 암호화 여부 확인 SHOW BINARY LOGS; +------------------+-----------+-----------+ | Log_name | File_size | Encrypted | +------------------+-----------+-----------+ | mysql-bin.000010 | 3047 | No | | mysql-bin.000011 | 512 | Yes | +------------------+-----------+-----------+ 7.5.3 mysqlbinlog 도구 활용 문제: 암호화된 바이너리 로그는 직접 열 수 없다 mysqlbinlog 는 바이너리 로그 내용을 확인하거나 시점 복구(PITR)를 할 때 많이 쓰는 도구입니다. 그런데 암호화된 바이너리 로그 파일을 직접 열면 에러가 발생 합니다. mysqlbinlog -vvv mysql-bin.000011 # → 파일이 암호화되어 있어서 읽을 수 없다는 에러 발생 ❌ 바이너리 로그 암호화 키는 MySQL 서버만 키링을 통해 접근할 수 있기 때문입니다. mysqlbinlog 는 키링에 직접 접근할 수 없습니다. 해결: MySQL 서버를 통해 읽기 mysqlbinlog -uroot -p -vvv --read-from-remote-server mysql-bin.000011 옵션 설명 --read-from-remote-server 파일을 직접 읽지 않고, MySQL 서버에 접속해서 바이너리 로그를 받아옴 mysqlbinlog ──요청──▶ MySQL 서버 (키링 접근 가능) │ 복호화 mysqlbinlog ◀──평문── MySQL 서버 💡 MySQL 서버가 바이너리 로그를 복호화해서 전달 하기 때문에 내용을 확인할 수 있습니다. ⚠️ 백업·복구 시 주의 백업해둔 암호화된 바이너리 로그를 나중에 사용하려면, 해당 키를 가진 MySQL 서버를 거쳐야 합니다. 그래서 바이너리 로그를 백업할 때는 키링 파일도 함께 백업 해야 합니다. ✍️ 마무리 정리 7.1 MySQL 서버의 데이터 암호화 TDE : 디스크에 쓸 때 암호화, 읽을 때 복호화. 사용자는 일반 테이블처럼 사용 2단계 키 관리 : 마스터 키(키링) → 테이블스페이스 키(데이터 파일 헤더) → 데이터 마스터 키 변경 시 테이블스페이스 키만 다시 암호화 하므로 빠름 버퍼 풀에 올라온 데이터는 복호화 상태 → 성능 영향은 크지 않음 압축과 함께 쓰면 압축 먼저, 암호화 나중 복제 소스와 레플리카는 각자의 마스터 키 사용, 키링 파일은 별도 백업 7.2 keyring_file 플러그인 설치 커뮤니티 에디션용, 마스터 키를 평문 파일 에 저장 → 파일 관리 주의 early-plugin-load 로 가장 먼저 로드 7.3 테이블 암호화 ENCRYPTION = 'Y' 로 생성, default_table_encryption 으로 기본값 설정 가능 응용 프로그램 암호화는 범위 검색·정렬 불가 , TDE는 제약 없음 암호화 테이블 이동 시 .cfp 파일 필수 7.4 언두 로그 및 리두 로그 암호화 innodb_undo_log_encrypt , innodb_redo_log_encrypt (8.0.16+) 켠 이후의 로그만 암호화, 끄더라도 기존 암호화 로그는 그대로 7.5 바이너리 로그 암호화 binlog_encryption (8.0.14+), 릴레이 로그도 함께 암호화 바이너리 로그 암호화 키 → 파일 키 → 로그 데이터 2단계
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
07장. 데이터 암호화. 『Real MySQL 8.0』 7장을 읽고, 핵심 개념을 쉽게 이해할 수 있도록 제 방식대로 정리한 글입니다. 📌 들어가기 전에 왜 데이터를 암호화할까? 개인정보, 결제 정보 같은 민감한 데이터 를 보호하기 위해서입니다. 서버의 디스크나 백업 파일이 유출되더라도, 암호화 키가 없으면 내용을 읽을 수 없게 만드는 것이 목적입니다. MySQL 8.0 암호화 대상 한눈에 보기 암호화 대상 설정 다루는 절 테이블(데이터 파일) ENCRYPTION = 'Y' 7.3 언두 로그 / 리두 로그 innodb_undo_log_encrypt , innodb_redo_log_encrypt 7.4 바이너리 로그 / 릴레이 로그 binlog_encryption 7.5 💡 테이블만 암호화하고 로그를…
Open source