- 핀테크 서비스처럼 중요한 정보를 저장하는 서비스에서 응용 프로그램에서 암호환 데이터를 데이터베이스 서버에서 다시 암호화하는 이중 암호화 방법을 선택하기도 한다.
- InnoDB 스토리지 엔지의 I/O 레이어에서만 데이터의 암호화 및 복호화 과정이 실행한다.
- MySQL 서버는 사용자의 쿼리를 처리하는 과정에서 테이블의 데이터가 암호화돼 있는지 여부를 식별할 필요가 없으며, 암호화된 테이블도 그렇지 않은 테이블과 동일한 처리 과정을 거친다.
- MySQL 내부와 사용자 입장에서 아무런 차이가 없기 때문에 이러한 암호화 방식을 가리켜
TDE, Transparent Data Encryption이라고 한다.
- TDE에서는 암호화 키는
키링 KeyRing 플러그인에 의해 관리된다.
- MySQL 8.0에서 지원되는 키링 플러그인은 다음과 같다. (커뮤니티 에디션에서는
keyring_file 플러그인만 사용할 수 있다.)
keyring_file File-Based 플러그인
keyring_encrypted_file Keyring 플러그인
keyring_okv KMIP 플러그인
keyring_aws Amazon Web Services Keyring 플러그인
- 다양한 플러그인이 제공되지만 마스터 키를 관리하는 방법만 다를 뿐 MySQL 서버 내부적으로 작동하는 방식은 모두 동일하다.
- MySQL 서버의 키링 플러그인은 2단계(2-Tier) 키 관리 방식을 사용한다.
- MySQL 서버의 데이터 암호화는
마스터 키 master key와 테이블스페이스 키 tablespace key라는 두 가지 종류의 키를 가지고 있다.
- 테이블스페이스 키는
프라이빗 키 private key라고도 한다. 테이블스페이스 키는 삭제되지 않는 이상 절대 변경되지 않으며, 서버 외부로 노출되지 않는다.
- 마스터 키는 외부에 노출될 수 있기 때문에 주기 적으로 바꿔줘야 한다.
- 데이터 페이지가 한 번 메모리에 적재되면 암호화되지 않은 테이블과 동일한 성능을 보인다.
- 하지만 버퍼 풀에 존재하지 않는 데이터 페이지를 읽어야 하는 경우 복호화 과정을 거치기 때문에 복호화 시간 동안 쿼리 처리가 지연될 것이다.
- 암호화된 테이블의 읽는 3
5배 정도 느리며, 쓰기의 경우에는 56배 정도 느린 것을 확인할 수 있다.
- 소스 서버와 레플리카 서버는 서로 다른 마스터 키를 갖도록 설정해야 한다.
- 마스터 키 자체가 레플리카로 복제되지 않기 때문에 테이블스페이스 키 또한 레플리카로 복제되지 않는다.
- 결국 서로 각자의 마스터 키와 테이블스페이스 키를 관리하기 때문에 복제 멤버들의 데이터 파일은 암호화되기 전의 값이 동일하더라도 실제 암호화된 데이터가 저장된 데이터 파일의 내용은 완전히 달라진다.
- my.cnf에서
early-plugin-load 시스템 변수에 keyring_file 플러그인을 위한 라이브러리 "keyring_file.so"를 명시하면 된다.
- 또한 마스터 키를 저장할 키링 파일의 경로를
keyring_file_data 설정에 명시하면 된다.
early-plugin-load = keyring_file.so
keyring_file_data = /very/secure/directory/tde_master.key
- 데이터 암호화 기능을 사용하는 테이블을 생성하거나 마스터 로테이션을 실행하면 키링 파일의 마스터 키가 초기화된다.
mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;
- 테이블을 생성할 때
ENCRYPTION='Y'만 넣으면 된다.
mysql> CREATE TABLE my_table(
id INT PRIMARY KEY
) ENCRYPTION='Y'
- 응용 프로그램에서 암호화하여 칼럼에 값을 넣는 경우 인덱스의 기능을 100% 활용할 수 없다.
- 예를 들어, 생년월일을 암호화한 경우 => 출생 연도 기준으로 정렬해서 상위 10개만 가져오는 등의 쿼리는 사용할 수가 없다.
- 응용 프로그램의 암호화와 MySQL 서버의 암호화 기능 중 선택해야 하는 상황이라면 고민할 필요 없이 MySQL 서버의 암호화 기능을 선택할 것을 권장한다.
- 테이블 암호화는 로그 파일에 전혀 영향을 주지 않는다.
- MySQL 8.0.16 버전부터는
innodb_undo_log_encrypt, innodb_redo_log_encrypt 시스템 변수를 이용해 InnoDB 스토리지 엔진의 리두 로그와 언두 로그를 암호화된 상태로 저장할 수 있게 개선됐다.
- 평문으로 저장하다가 암호화가 활성화되면 그때부터 생성되는 로그에 대해 암호화해서 저장한다.
- 리두 로그와 언두 로그 데이터 모두 각각의 테이블스페이스 키로 암호화되고, 테이블 스페이스 키는 다시 마스터 키로 암호화된다.
- 즉,
ALTER INSTANCE ROTATE INNODB MASTER KEY 명령이 실행되면 새로운 마스터 키가 발급되고 테이블 암호화에 사용된 테이블스페이스 키와 동일하게 그 새로운 마스터 키에 의해 다시 암호화된다.
- 일반적으로 언두 로그와 리두 로그는 길지 않은 시간 동안의 데이터만 가지기 때문에 크게 보안에 민감하지 않을 수 있지만 바이너리 로그는 의도적으로 상당히 긴 시간 동안 보관하는 서비스도 있고 때로는
증분 백업 Incremental Backup을 위해 바이너리 로그를 보관하기도 한다.
- 이런 이유로 바이너리 로그 파일의 암호화는 상황에 따라 중요도가 높아질 수도 있다.
- 바이너리 로그와 릴레이 로그 파일의 데이터는 파일 키로 암호화해서 디스크로 저장하고, 파일 키는 "바이너리 로그 암호화 키"로 암호화해서 각 바이너리 로그와 릴레이 로그 파일의 헤더에 저장된다.
- 바이너리 로그 암호화 키는 다음과 같이 변경(Rotation)할 수 있다.
mysql> ALTER INSTANCE ROTATE BINLOG MASTER KEY;
- 한 번 바이너리 로그 파일이 암호화되면 바이너리 로그 암호화 키가 없으면 복호화할 수 없다.
- 그런데 바이너리 로그 암호화 키는 MySQL 서버만 가지고 있어서 복호화가 불가능하다.
- MySQL 서버와 관계없이
mysqlbinlog 도구만으로 복호화할 방법이 없다.