MySQL 테이블에 TDE(투명한 암호화) 적용(Windows 버전)

페이지 업데이트 :
페이지 생성 날짜 :

운영 환경

MySQL을 사용합니다.
  • MySQL 8.0 커뮤니티 에디션
윈도우
  • 윈도우 11

필수 구성 요소

MySQL을 사용합니다.
  • MySQL 8.0 커뮤니티 에디션
  • MySQL 8.0 엔터프라이즈 에디션
윈도우
  • 윈도우 11
  • 윈도우 10
윈도우 서버
  • 윈도우 서버 2022
  • 윈도우 서버 2019
  • 윈도우 서버 2016
  • 윈도우 서버 2012 R2

전제 조건

  • MySQL용 데이터베이스가 설치되어 있습니다.

투명한 암호화 정보

Enterprise Transparent Data Encryption은 이름에서 알 수 있듯이 그렇지 않은 암호화 기술보다 더 안전한 암호화 기술입니다. 일반적으로 암호화를 할 때 암호화 및 복호화 처리를 수행해야 하기 때문에 구현자에게 부담이 되는 경우가 많습니다. 이 이름 "투명"의 의미는 구현자가 프로세스를 변경하지 않고도 암호화할 수 있다는 것입니다. 따라서 처음에 설정을 약간 변경하면 나머지는 무단으로 암호화되므로 매우 효과적인 보안 조치입니다.

그러나 "아무것도 변경할 필요가 없다"는 문구에서 알 수 있듯이 실제로 데이터베이스에 로그인하면 데이터를 정상적으로 볼 수 있고, 프로그램에서 데이터베이스 레코드를 가져오면 데이터를 정상적으로 볼 수 있습니다. 취득한 데이터가 암호화되어 있으면 프로세스를 변경해야 하므로 "프로세스를 변경할 필요가 없다"라는 문구와 일치하지 않습니다.

그런 다음 MySQL에서 투명한 암호화가 정확히 무엇인지 암호화되고 "저장된 데이터베이스 파일" 또는 "테이블 파일"이 암호화 대상입니다. 나중에 확인하겠지만, 파일을 직접 열어도 내용을 볼 수 없도록 암호화만 하기 때문에 실제 동작에서는 데이터베이스에 로그인되지 않도록 조작할 필요가 있습니다.

테이블을 정상적으로 생성하고 내용을 확인합니다.

먼저 테이블과 레코드를 정상적으로 생성해 보겠습니다. 원하는 대로 만들 수 있지만 이 경우 Workbench에서 SQL을 실행하여 만듭니다. 이 경우 테이블에 대해 투명한 암호화를 설정할 계획이므로 데이터베이스를 정상적으로 생성합니다.

CREATE DATABASE `test_database`

테이블도 정상적으로 만들어져 있습니다. 열의 내용은 무엇이든 될 수 있습니다.

CREATE TABLE `plain_user` (
  `id` int NOT NULL,
  `name` varchar(32) ,
  `age` int ,
  `address` varchar(256) ,
  `phone` varchar(32) ,
  `email` varchar(128) ,
  `remarks` varchar(1024) ,
  `height` decimal(5, 2) ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

또한 암호화를 확인하기 위해 임의의 레코드를 넣을 것입니다.

INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('1','名前1','11','宮城県仙台市1','000-0000-0001','example1@example.com','備考1','170.00');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('2','名前2','12','宮城県仙台市2','000-0000-0002','example2@example.com','備考2','171.01');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('3','名前3','13','宮城県仙台市3','000-0000-0003','example3@example.com','備考3','172.02');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('4','名前4','14','宮城県仙台市4','000-0000-0004','example4@example.com','備考4','173.03');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('5','名前5','15','宮城県仙台市5','000-0000-0005','example5@example.com','備考5','174.04');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('6','名前6','16','宮城県仙台市6','000-0000-0006','example6@example.com','備考6','175.05');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('7','名前7','17','宮城県仙台市7','000-0000-0007','example7@example.com','備考7','176.06');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('8','名前8','18','宮城県仙台市8','000-0000-0008','example8@example.com','備考8','177.07');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('9','名前9','19','宮城県仙台市9','000-0000-0009','example9@example.com','備考9','178.08');
INSERT INTO `test_database`.`plain_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('10','名前10','20','宮城県仙台市10','000-0000-0010','example10@example.com','備考10','179.09');

데이터베이스나 테이블을 만들면 기본적으로 다음 폴더에 만들어집니다.

  • C:\ProgramData\MySQL\MySQL 서버 8.0\데이터

ProgramData 폴더가 숨겨져 있으므로 탐색기 설정에서 표시되도록 합니다.

폴더에 만든 데이터베이스 이름의 폴더가 있으므로 열어 봅니다.

내부에는 테이블별 파일이 있습니다.

메모장과 같은 텍스트 편집기에서 이 파일을 엽니다. 바이너리 파일이기 때문에 기본적으로 잘 모르는 텍스트 줄이 있다고 생각합니다. 하단을 보시면 등록된 기록의 본문을 보실 수 있습니다.

이러한 방식으로 암호화되지 않으면 파일을 직접 열어도 레코드의 내용을 알 수 있습니다. 내부에 무엇이 있는지 알기 위해 데이터베이스에 로그인할 필요가 없습니다.

투명 암호화 설정 구성

투명 암호화를 사용하려면 플러그인을 설치해야 합니다. 먼저 플러그인이 명령에 포함되어 있는지 확인합니다.

시작 메뉴에서 "MySQL 8.0 Command Line Client"를 선택하여 시작하십시오.

비밀번호를 입력하고 로그인한 후 다음 명령을 입력합니다.

SELECT PLUGIN_NAME,PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';

아직 설치하지 않았으므로 비어 있어야 합니다.

이제 플러그인을 설정해 보겠습니다. 먼저 다음 폴더를 만듭니다. 사실, 어디에서 생성하는지, 어떤 이름인지는 중요하지 않습니다. 나중에 키 파일을 저장할 위치로 지정합니다.

  • C:\ProgramData\MySQL\mysql-keyring

그런 다음 텍스트 편집기에서 다음 파일을 엽니다.

  • C:\ProgramData\MySQL\MySQL 서버 8.0\my.ini

하단의 빈 공간에 다음 텍스트를 추가하고 저장합니다. 관리자 권한으로 저장할 수 없는 경우 다른 위치에 저장한 다음 파일을 덮어쓸 수 있습니다.

early-plugin-load=keyring_file.dll
keyring_file_data=C:\ProgramData\MySQL\mysql-keyring\keyring

MySQL 서비스를 다시 시작합니다. 명령을 사용하여 다시 시작할 수도 있습니다.

다시 시작하면 지정된 폴더에 파일이 자동으로 생성됩니다.

check plug-in 명령을 다시 실행하여 플러그인이 설치되었는지 확인할 수 있습니다.

SELECT PLUGIN_NAME,PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';

암호화된 테이블 만들기

이제 암호화된 테이블을 만들어 보겠습니다. 이전 테이블과 비슷한 테이블을 만들되 이번에는 옵션에 ENCRYPTION='Y' 추가합니다. 이 암호화 설정은 현재 GUI에서 사용할 수 없는 것 같으므로 명령으로 설정해야 합니다.

CREATE TABLE `encrypt_user` (
  `id` int NOT NULL,
  `name` varchar(32) ,
  `age` int ,
  `address` varchar(256) ,
  `phone` varchar(32) ,
  `email` varchar(128) ,
  `remarks` varchar(1024) ,
  `height` decimal(5, 2) ,
PRIMARY KEY (`id`)
) ENCRYPTION='Y' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

덧붙여서 플러그인을 구성하기 전에 암호화 된 테이블을 만들려고해도 다음과 같은 오류가 표시됩니다.

Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
キーリングからマスターキーが見つかりません。キーリングが正常にロードされ、初期化されているかどうかをサーバーログで確認してください。

데이터가 없으면 암호화되어 있는지 알 수 없기 때문에 같은 데이터를 넣어 보겠습니다.

INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('1','名前1','11','宮城県仙台市1','000-0000-0001','example1@example.com','備考1','170.00');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('2','名前2','12','宮城県仙台市2','000-0000-0002','example2@example.com','備考2','171.01');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('3','名前3','13','宮城県仙台市3','000-0000-0003','example3@example.com','備考3','172.02');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('4','名前4','14','宮城県仙台市4','000-0000-0004','example4@example.com','備考4','173.03');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('5','名前5','15','宮城県仙台市5','000-0000-0005','example5@example.com','備考5','174.04');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('6','名前6','16','宮城県仙台市6','000-0000-0006','example6@example.com','備考6','175.05');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('7','名前7','17','宮城県仙台市7','000-0000-0007','example7@example.com','備考7','176.06');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('8','名前8','18','宮城県仙台市8','000-0000-0008','example8@example.com','備考8','177.07');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('9','名前9','19','宮城県仙台市9','000-0000-0009','example9@example.com','備考9','178.08');
INSERT INTO `test_database`.`encrypt_user` (`id`,`name`,`age`,`address`,`phone`,`email`,`remarks`,`height`) VALUES ('10','名前10','20','宮城県仙台市10','000-0000-0010','example10@example.com','備考10','179.09');

encrypt_user 테이블 파일이 생성되었으므로 내용을 확인합시다.

파일이 암호화되어 레코드의 내용을 확인할 수 없습니다.

당분간은 더 이상 서버에 로그인하여 테이블 파일을 직접 훔치는 것만으로 제3자가 내부 레코드를 읽는 것에 대해 걱정할 필요가 없습니다. 구현을 전혀 변경할 필요가 없기 때문에 쉬운 보안 설정이라고 생각합니다.

그러나 데이터베이스에 로그인하면 데이터를 정상적으로 볼 수 있습니다. 보안 수준을 높이려면 데이터베이스 로그인 계정을 잘 관리하고 별도의 암호화 메커니즘을 도입해야 합니다.

도중에 암호화된 테이블로 변환

암호화되지 않은 테이블을 처음 생성한 경우 나중에 암호화된 테이블로 변환할 수 있습니다. 이 경우 다음 SQL을 사용하여 변환할 수 있습니다.

use <データベース名>;
ALTER TABLE <テーブル名> ENCRYPTION='Y';

본보기

use test_database;
ALTER TABLE plain_user ENCRYPTION='Y';

다만, 기록이 많을 경우 테이블 파일을 모두 다시 작성하기 때문에 시간이 걸리기 때문에 주의하시기 바랍니다.