MySQL 5.7 InnoDB Tablespace Encryption

eric0435發表於2023-03-10

InnoDB Tablespace Encryption

InnoDB支援對儲存file-per-table表空間中的InnoDB表中的資料進行加密。該特性為物理表空間資料檔案提供靜態加密。

InnoDB表空間加密使用兩層加密金鑰架構,由主加密金鑰和表空間金鑰組成。當一個InnoDB表被加密時,表空間金鑰被加密並儲存在表空間頭中。當應用程式或經過認證的使用者想要訪問加密的表空間資料時,InnoDB使用一個主加密金鑰來解密表空間金鑰。表空間金鑰的解密版本永遠不會改變,但主加密金鑰可以根據需要改變。此操作稱為主鍵旋轉。

InnoDB表空間加密特性依賴於keyring外掛進行主加密金鑰管理。

所有MySQL版本都提供了keyring_file外掛,該外掛將主加密金鑰資料儲存在keyring_file_data配置選項指定的位置的keyring檔案中。

非企業版MySQL中的InnoDB表空間加密特性使用keyring_file外掛進行加密金鑰管理,這並不是一個符合法規的解決方案。安全標準,如PCI,FIPS和其他要求使用金鑰管理系統來保護、管理和保護金鑰庫或硬體安全模組(hsm)中的加密金鑰。

MySQL企業版提供了keyring_okv外掛,其中包括一個KMIP客戶端(KMIP 1.1),它與Oracle金鑰庫(OKV)一起工作,提供加密金鑰管理。當InnoDB表空間加密使用OKV進行加密金鑰管理時,該特性被稱為“MySQL企業”透明資料加密(TDE)。

一個安全、健壯的加密金鑰管理解決方案(如OKV)對於安全性和符合各種安全標準至關重要。在其他好處中,使用金鑰庫可確保金鑰安全儲存,永遠不會丟失,並且只有授權的金鑰管理員知道。金鑰庫還維護加密金鑰歷史記錄

InnoDB表空間加密支援AES (Advanced encryption Standard)塊加密演算法。它採用ECB (Electronic Codebook)塊加密方式對錶空間金鑰進行加密CBC (Cipher Block chainaining)塊加密方式,用於資料加密

InnoDB表空間加密前提條件

必須安裝和配置keyring外掛(keyring_file外掛或keyring_okv外掛)。Keyring外掛安裝在啟動時使用--early-plugin-load選項執行。提前載入可以確保外掛在InnoDB儲存引擎初始化之前可用。

一次只能啟用一個keyring外掛。不支援啟用多個密匙環外掛。

一旦在MySQL例項中建立了加密表,在建立加密表時載入的keyring外掛必須在InnoDB初始化之前使用--early-plugin-load選項繼續載入。如果不這樣做,會導致啟動和恢復InnoDB時出現錯誤。

啟用加密模組

mysql> INSTALL PLUGIN keyring_file soname 'keyring_file.so';
Query OK, 0 rows affected (0.09 sec)

建立金鑰檔案目錄

[mysql@localhost ~]$ mkdir -p /mysqldata/mysql/mysql-keyring/
[mysql@localhost ~]$ chown -R mysql:mysql /mysqldata/mysql/mysql-keyring/
[mysql@localhost ~]$ chmod -R 775 /mysqldata/mysql/mysql-keyring/

設定加密key存放路徑

mysql> set global keyring_file_data='/mysqldata/mysql/mysql-keyring/keyring';
Query OK, 0 rows affected (0.00 sec)


上訴兩個步驟都是臨時的,重啟服務都會失效,我們把配置寫到配置檔案裡,確保重啟服務後也能生效

[mysqld]
early-plugin-load=keyring_file.so
keyring_file_data=/mysqldata/mysql/mysql-keyring/keyring

檢視key的存放路徑

mysql> show global variables like '%keyring_file_data%';
+-------------------+----------------------------------------+
| Variable_name     | Value                                  |
+-------------------+----------------------------------------+
| keyring_file_data | /mysqldata/mysql/mysql-keyring/keyring |
+-------------------+----------------------------------------+
1 row in set (0.02 sec)

要驗證keyring外掛是否處於活動狀態,請使用SHOW PLUGINS語句或查詢INFORMATION_SCHEMA.PLUGINS表。例如:

mysql> show plugins;
+----------------------------+----------+--------------------+-----------------+---------+
| Name                       | Status   | Type               | Library         | License |
+----------------------------+----------+--------------------+-----------------+---------+
| keyring_file               | ACTIVE   | KEYRING            | keyring_file.so | GPL     |
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL            | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL            | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL            | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL            | GPL     |
+----------------------------+----------+--------------------+-----------------+---------+
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
    -> FROM INFORMATION_SCHEMA.PLUGINS
    -> WHERE PLUGIN_NAME LIKE 'keyring%';
+--------------+---------------+
| PLUGIN_NAME  | PLUGIN_STATUS |
+--------------+---------------+
| keyring_file | ACTIVE        |
+--------------+---------------+
1 row in set (0.00 sec)

必須啟用innodb_file_per_table選項(預設值)。InnoDB表空間加密只支援每表一個檔案的表空間。或者,您可以指定TABLESPACE='innodb_file_per_table'選項,用於建立加密表或修改現有表以啟用加密。

mysql> show variables like '%innodb_file_per_table%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.01 sec)

在對生產資料使用InnoDB表空間加密特性之前,請確保已採取措施防止丟失主加密金鑰。如果主加密金鑰丟失,則無法恢復加密表空間檔案中儲存的資料。如果您正在使用keyring_file外掛,建議您在建立第一個加密表之後以及主金鑰旋轉前後立即建立keyring檔案的備份。keyring檔案位置由keyring_file_data配置選項定義。如果您正在使用keyring_okv外掛,請確保您已經執行了必要的keyring_okv外掛和Oracle金鑰庫(OKV)配置。

開啟和關閉InnoDB表空間加密

要為一個新的InnoDB表啟用加密,在create table語句中指定encryption選項。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION='Y';
Query OK, 0 rows affected (0.01 sec)

要對現有的InnoDB表啟用加密,請在alter table語句中指定encryption選項。

mysql> alter table abc encryption='y';
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> show create table abc;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                            |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| abc   | CREATE TABLE `abc` (
  `a` int(11) NOT NULL,
  PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ENCRYPTION='y' |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

使用alter table設定encryption ='N'來禁用InnoDB表的加密功能

mysql> alter table abc encryption='n';
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0
mysql> show create table abc;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                            |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| abc   | CREATE TABLE `abc` (
  `a` int(11) NOT NULL,
  PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ENCRYPTION='n' |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

InnoDB表空間加密和主金鑰輪換
主加密金鑰應該定期輪換,只要您懷疑金鑰可能已被洩露。

主金鑰輪換是一個原子的例項級操作。每次輪換主加密金鑰時,MySQL例項中的所有表空間金鑰都將重新加密並儲存回各自的表空間頭中。作為原子操作,一旦啟動輪換操作,所有表空間金鑰都必須重新加密成功。如果主金鑰輪換因伺服器故障而中斷,InnoDB將在伺服器重啟時前滾該操作。

輪換主加密金鑰只會更改主加密金鑰並重新加密表空間金鑰。它不解密或重新加密相關的表空間資料

輪換主加密金鑰,執行以下命令:

[root@localhost ~]# cd /mysqldata/mysql/mysql-keyring/
[root@localhost mysql-keyring]# ll
total 4
-rw-r-----. 1 mysql mysql 155 Mar  3 17:20 keyring
mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;
Query OK, 0 rows affected (0.00 sec)
[root@localhost mysql-keyring]# ll
total 4
-rw-r-----. 1 mysql mysql 283 Mar 10 15:58 keyring

alter instance rotate innodb master key支援併發DML。但是,它不能與create table ... encryption或alter table ... encryption操作一起併發執行,採用鎖來防止這些語句併發執行時可能產生的衝突。如果一個衝突的語句正在執行,那麼它必須在另一個語句執行之前完成。

InnoDB表空間加密與恢復
ALTER INSTANCE ROTATE INNODB MASTER KEY語句僅在主資料庫和從資料庫所執行的MySQL版本支援表空間加密特性的複製環境中被支援。

成功的ALTER INSTANCE ROTATE INNODB MASTER KEY語句被寫入二進位制日誌,用於在slave上覆制。

如果一個ALTER INSTANCE ROTATE INNODB MASTER KEY語句失敗,它不會被記錄到二進位制日誌中,也不會被複制到slave上。

如果keyring外掛安裝在主節點上而從節點沒有安裝,複製ALTER INSTANCE ROTATE INNODB MASTER KEY操作失敗。

如果keyring_file外掛同時安裝在主伺服器和從伺服器上,但是從伺服器上沒有keyring檔案,假設keyring檔案資料沒有快取在記憶體中,複製的ALTER INSTANCE ROTATE INNODB MASTER KEY語句將在從伺服器上建立keyring檔案。如果可用的話,ALTER INSTANCE INNODB MASTER KEY使用快取在記憶體中的keyring檔案資料。

識別使用InnoDB表空間加密的表
當在CREATE TABLE或ALTER TABLE語句中指定了ENCRYPTION選項時,它將記錄在INFORMATION_SCHEMA.TABLES的CREATE_OPTIONS欄位中。可以查詢該欄位以識別MySQL例項中的加密表。

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES
    -> WHERE CREATE_OPTIONS LIKE '%ENCRYPTION="Y"%';
+--------------+------------+-------------------------------------------------------+
| TABLE_SCHEMA | TABLE_NAME | CREATE_OPTIONS                                        |
+--------------+------------+-------------------------------------------------------+
| test         | t1         | ENCRYPTION="Y"                                        |
| test         | ts02       | row_format=COMPRESSED KEY_BLOCK_SIZE=4 ENCRYPTION="Y" |
| test         | ts03       | COMPRESSION="zlib" ENCRYPTION="Y"                     |
+--------------+------------+-------------------------------------------------------+
3 rows in set (0.42 sec)

InnoDB表空間加密使用說明
a.如果伺服器在正常執行期間退出或停止,建議使用之前配置的相同加密設定重新啟動伺服器。

b.第一個主加密金鑰是在對第一個新表或現有表進行加密時生成的。

c.主金鑰輪換會重新加密表空間金鑰,但不會改變表空間金鑰本身。要更改表空間金鑰,必須使用alter table tbl_name encryption禁用並重新啟用表加密,這是一個ALGORITHM=COPY操作來重建表。

d.Keyring_file外掛使用說明
如果keyring檔案為空或缺失,第一次執行ALTER INSTANCE ROTATE INNODB MASTER KEY將建立一個主加密金鑰。

解除安裝keyring_file外掛不會刪除現有的keyring檔案。

建議不要將keyring檔案與表空間資料檔案放在同一個目錄下。keyring檔案的位置由keyring_file_data選項指定。

在執行時修改keyring_file_data選項或使用新的keyring_file_data設定重新啟動伺服器可能導致以前加密的表不可訪問,從而導致資料丟失。

InnoDB表空間加密限制
.系統目前只支援AES (Advanced Encryption Standard)加密演算法。InnoDB表空間加密使用ECB (Electronic Codebook)塊加密方式對錶空間金鑰進行加密,使用CBC (Cipher block Chaining)塊加密方式對資料進行加密。

.修改表的ENCRYPTION屬性是一個ALGORITHM=COPY操作。不支援ALGORITHM=INPLACE。

.InnoDB表空間加密只支援儲存在file-per-table表空間中的InnoDB表。儲存在其他InnoDB表空間型別中的表不支援加密,包括普通表空間、系統表空間、undo log表空間和臨時表空間。

.不能將加密表從file-per-table表空間移動或複製到不支援的InnoDB表空間型別。

.表空間加密只適用於表空間中的資料。重做日誌、undo日誌或二進位制日誌中的資料不加密。

.目前不支援直接從keyring_file外掛遷移到keyring_okv外掛,反之亦然。更改密匙環外掛需要解密表,解除安裝當前的密匙環外掛,安裝和配置其他密匙環外掛,並重新加密表。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-2939131/,如需轉載,請註明出處,否則將追究法律責任。

相關文章