1. MySQL의 데이터 암호화 지원

    1. 5.7버전부터 지원되기 시작한 데이터 암호화 기능은 처음에는 데이터 파일(테이블스페이스)에 대해서만 암호화 기능이 제공됐음
    2. 8.0버전이 되면서 데이터 파일뿐만 아니라 리두 로그나 언두 로그, 복제를 위한 바이너리 로그 등도 모두 암호화
    3. 데이터베이스에서는 테이블 단위로 암호화를 적용(응용 프로그램에서는 레코드 단위로 적용)
  2. MySQL 서버의 데이터 암호화

    Untitled

    1. MySQL에서는 위처럼 데이터베이스 서버와 디스크 사이의 데이터 입/출력 지점에서 암호화 또는 복호화를 수행(스토리지 엔진 레벨에서만 암호화/복호화 수행)
    2. 따라서, 디스크 입출력외의 부분에서는 암호화/복호화를 하지 않아도 됨
    3. 그렇기 때문에 데이터 암호화가 되어 있더라도 MySQL내부와 사용자는 전혀 고려를 하지 않아도 되며 이러한 방식을 **TDE(Transparent Data Encryption)**이라고 함
  3. 키 관리

    Untitled

    1. MySQL서버의 TDE에서 암호화 키는 키링(KeyRing) 플러그인에 의해 관리
    2. 커뮤니티 버전에서는 keyring_file 플러그인만 사용 가능함(엔터프라이즈는 추가 지원)
    3. MySQL에서는 암호화를 마스터 키, **테이블스페이스 키(프라이빗 키)**라는 두가지 키를 가짐
    4. MySQL서버는 HashiCorp Vault같은 외부 키 솔루션이나 디스크의 파일(keyring_file 등)에서 마스터 키를 가져오고 암호화된 테이블이 생성될 때마다 해당 테이블을 위한 임의의 테이블스페이스 키를 발급하 는 방식을 사용
    5. 키링 플러그인은 마스터 키를 생성/관리하는 부분만 담당하기 때문에 어떤 플러그인을 사용하더라도 암호화된 테이블 처리는 동일하게 처리됨
    6. 테이블스페이스 키는 마스터 키를 통해 암호화되어 있으며, 테이블스페이스 키를 해당 테이블의 헤더 정보에 저장해둔다(테이블이 삭제되지 않는 한 절대 변경되지 않음)
    7. 외부로 노출되는 일이 없기 때문에 테이블스페이스 키를 주기적으로 변경하지 않아도 취약하지 않음
    8. ALTER INSTANCE ROTATE INNODB MASTER KEY;
    9. 위 명령으로 마스터 키를 변경하면, 기존의 마스터 키를 이용해 각 테이블의 테이블스페이스 키를 복호화한 다음 새로운 마스터 키로 다시 암호화 수행
    10. 마스터 키가 변경되는 동안 테이블스페이스 키 자체와 데이터 파일의 데이터는 변경되지 않음
    11. 이렇게 이중 암호화를 사용하여 시스템 부하를 피함(마스터 키 변경시마다 테이블스페이스 키자체를 수정하지 않음으로써)
    12. MySQL 서버의 TDE에서 지원되는 암호화 알고리즘
      1. AES 256비트(이외의 알고리즘은 지원X)
      2. 테이블스페이스 키 → ASE-256 ECB(Electronic CodeBooK)
      3. 실제 데이터 파일 → AES-256 CBC(Cipher Block Chaining)
  4. 암호화의 성능

    1. MySQL 서버의 암호화는 TDE 방식이기 때문에 디스크로부터 한 번 읽은 데이터 페이지는 복호화되어 InnoDB의 버퍼 풀에 적재
    2. 하지만, 쿼리가 InnoDB 버퍼 풀에 존재하지 않는 경우 복호화 과정을 거치기 때문에, 복호화 시간 동안 지연
    3. 추가로 암호화된 테이블이 변경되면 다시 디스크로 동기화될 때 암호화되어야하기 때문에 시간이 지연될 수 있음
    4. 하지만 InnoDB에서의 이런 작업들은 백그라운드 스레드에서 수행하기 때문에 실제 쿼리가 지연되는 것은 아님
  5. AES(Advanced Encryption Standard) 암호화 알고리즘

    1. 암호화하고자 하는 평문의 길이가 짧은 경우 암호화 키의 크기에 따라 암호화 결과의 용량이 커질 수도 있음
    2. 하지만 데이터 페이지는 보통 암호화 키보다는 크기 때문에 평문과 동일한 크기를 반환하게 됨
    3. 즉, 암호화를 하더라도 InnoDB 버퍼 풀의 효율이 달라지거나 메모리 사용 효율이 떨어지지는 않음
    4. 같은 테이블에 대해 암호화와 압축이 동시에 적용되면 MySQL서버는 압축을 수행한 뒤 암호화를 수행
  6. 암호화와 복제

    1. MySQL에서의 복제는 Master의 모든 사용자 데이터를 동기화하기 때문에 실제 데이터 파일도 동일할 것이라 예측됨
    2. 하지만 TDE를 이용한 암호화 사용 시 마스터 키와 테이블스페이스 키는 그렇지 않음
    3. 마스터 키 자체가 Slave로 복제되지 않기 때문에 서로 다른 마스터 키를 갖게 됨
    4. 그렇기 때문에 Master/Slave에서 암호화된 데이터는 완전히 다른 값을 가지게 됨
    5. ALTER INSTANCE ROTATE INNODB MASTER KEY;
    6. 위 명령을 수행하면 해당 명령은 Slave에게 가지만 각각 다른 마스터 키를 가지게 됨
  7. 테이블 암호화

    CREATE TABLE tab_encrypted (
    	id INT,
    	data VARCHAR(100),
    	PRIMARY KEY(id)
    ) ENCRYPTION='Y';
    
    1. 테이블 생성 마지막 **ENCRYPTION='Y'**를 통해 암호화 테이블을 생성 가능
    2. 매번 생성할 때 명령을 사용하는 것은 부담이 있을 땐 default_table_encryption 시스템 변수를 ON으로 설정하면 자동으로 암호화 테이블 생성
  8. 응용 프로그램 암호화와의 비교

    1. 응용 프로그램에서 암호화해서 MySQL서버에 저장하는 경우도 있는데, 이경우 해당 레코드의 암호화여부를 MySQL서버는 알지 못함
    2. 또한 암호화된 레코드를 저장하기 때문에 인덱스를 활용하고 싶어도 활용하지 못함
    3. 응용 프로그램 암호화와 MySQL서버의 암호화 기능 중 선택해야 하는 경우에는 MySQL서버의 암호화가 권장됨
    4. 하지만 경우에 따라 달라지기 때문에 신중하게 결정
  9. 테이블 스페이스 이동

    1. 테이블을 다른 서버로 복사해야 하는 경우 또는 특정 테이블의 데이터 파일만 백업했다가 복구하는 경우
    2. 테이블스페이스 이동(Export & Import) 기능이 덤프했다가 복구하는 방식보다 훨씬 효율적
    3. 하지만, TDE가 적용된 경우 Master/Slave의 마스터 키가 다르게 관리되기 때문에 주의해야함
    4. 암호화 사용하지 않은 경우
      1. FLUSH TABLES source_table FOR EXPORT;
      2. 위 명령 실행시 source_table의 저장되지 않은 변경 사항을 모두 디스크로 기록하고, 더이상 source_table에 접근할 수 없게 잠금 실행
      3. 동시에 source_table의 구조를 source_table.cfg 파일로 기록
      4. 그러고 source_table.ibd, source_table.cfg 파일을 목적지 서버로 복사
      5. 복사 완료후 UNLOCK TABLE 명령으로 source_table을 사용할 수 있게 하면 됨
    5. 암호화를 사용하는 경우
      1. FLUSH TABLES source_table FOR EXPORT;
      2. 명령 실행시 임시로 사용할 마스터 키를 발급해서 source_table.cfg 파일로 기록
      3. 그리고, 암호화된 테이블의 테이블스페이스 키를 기존 마스터 키로 복호화 → 임시로 발급한 마스터 키로 다시 암호화하고 테이블 헤더에 저장
      4. 위 과정때문에 암호화 테이블의 경우 테이블스페이스 이동을 위해 임시 마스터 키가 저장된 *.cfg 파일을 함께 복사
  10. 언두 로그 및 리두 로그 암호화

    1. 언두 로그 및 리두 로그는 각각의 프라이빗 키를 사용해서 암호화
    2. 암호화를 활성화하는 경우 적재된 로그가 모두 암호화되는 것이 아닌, 설정한 시간부터 이후로 적재되는 로그만 암호화
    3. 해당 프라이빗 키는 마스터 키로 암호화되어 리두 로그 파일, 언두 로그 파일의 헤더에 저장됨
    4. 리두 로그 암호화 확인 명령어 : SHOW GLOBAL VARIABLES LIKE ‘innodb_redo_log_encrypt’;
  11. 바이너리 로그 암호화

    1. 바이너리 로그는 언두, 리두 로그와는 달리 상당히 긴 시간 보관하기도 하기 때문에 바이너리 로그의 암호화는 중요도가 높아질 수 있음
    2. 필요할 때 더 찾아보자