MySQL 中的加密:使用主密鑰

期待新課程開始招生 “數據庫” 我們將繼續發布一系列關於 MySQL 加密的文章。

MySQL 中的加密:使用主密鑰

在本系列的上一篇文章中(MySQL 中的加密:Keystore)我們討論了密鑰庫。 在本文中,我們將了解如何使用主密鑰並討論信封加密的優點和缺點。 

信封加密背後的想法是,用於加密的密鑰(表空間密鑰)使用另一個密鑰(主密鑰)進行加密。 表空間密鑰實際上用於加密數據。 從圖形上來說,它可以這樣表示:

MySQL 中的加密:使用主密鑰

主密鑰位於密鑰環中,表空間密鑰位於加密的表空間標頭中(位於表空間的第 0 頁)。 

上圖中:

  • 表A使用密鑰1(Key 1)加密。 密鑰1使用主密鑰加密,並加密存儲在表A的表頭中。

  • 表 B 使用密鑰 2 加密。 密鑰 2 使用主密鑰(屏蔽密鑰)進行加密,並加密存儲在表 B 的標頭中。

  • 等。

當服務器需要解密表A時,它從存儲中檢索主密鑰,從表A的表頭中讀取加密密鑰1,並對密鑰1進行解密。解密後的密鑰1緩存在服務器內存中,用於解密表A 。

InnoDB的

在InnoDB中,實際的加密和解密是在I/O層完成的。 也就是說,頁面在刷新到磁盤之前進行加密,並在從磁盤讀取之後立即進行解密。

在InnoDB中,加密僅在表空間級別起作用。 默認情況下,所有表都創建在單獨的表空間中(每表文件表空間)。 換句話說,創建的表空間只能包含一個表。 儘管您也可以在主表空間中創建表(通用表空間)。 但無論如何,表總是位於某個表空間中。 由於加密是在表空間級別進行的,因此它要么完全加密,要么不加密。 也就是說,不可能只加密主表空間中的部分錶。 

如果由於某種原因禁用了 file-per-table,則所有表都會在系統表空間內創建。 在 用於 MySQL 的 Percona 服務器 您可以使用 innodb 變量加密系統表空間系統表空間加密或使用加密線程,但這仍然是一個實驗性功能。 MySQL沒有這個。

在繼續之前,我們需要看一下主密鑰 ID 的結構。 它由UUID、KEY組成ID 和前綴“INNODBKey”。 它看起來像這樣:INNODBKey-UUID-KEYID。

UUID 是具有加密表空間的服務器的 uuid。 鑰匙ID只是一個不斷增加的值。 第一次創建主密鑰KEY時ID為1。在密鑰輪換期間,當創建新的主密鑰時,KEYID = 2 等等。 我們將在本系列的下一篇文章中詳細討論主密鑰輪換。

現在我們知道主密鑰標識符是什麼樣子,讓我們看看加密的表空間標頭。 當表空間被加密時,加密信息被添加到標頭中。 它看起來像這樣:

MySQL 中的加密:使用主密鑰

密鑰 ID 是密鑰ID來自我們已經討論過的主密鑰ID。 UUID是服務器的uuid,也用於主密鑰標識符。 TABLESPACE KEY - 表空間密鑰,由服務器隨機生成的 256 位組成。 初始化向量 (IV) 也由 256 個隨機生成的位組成(儘管它應該是 128 位)。 IV 用於初始化 AES 加密和解密(256 位中,僅使用了 128 位)。 最後是 TABLESPACE KEY 和 IV 的 CRC32 校驗和。

一直以來,我都在稍微簡化一下,說標頭包含表空間的加密密鑰。 事實上,表空間密鑰和初始化向量是使用主密鑰一起存儲和加密的。 請記住,在加密表空間密鑰和初始化向量之前,會為它們計算 CRC32。

為什麼需要 CRC32?

簡而言之,就是保證主密鑰的有效性。 解密表空間密鑰和初始化向量後,計算校驗和並與標頭中存儲的 CRC32 進行比較。 如果校驗和匹配,則我們擁有正確的主密鑰和表空間密鑰。 否則,表空間將被標記為丟失(無論如何我們都無法解密它)。

你可能會問:什麼時候進行密鑰驗證? 答案是服務器啟動時。 具有加密表/表空間的服務器在啟動時讀取 UUID、KEY從標頭中獲取 ID 並生成主密鑰 ID。 然後,它從密鑰環中獲取所需的主密鑰,解密表空間密鑰,並驗證校驗和。 再次,如果校驗和匹配,則一切正常,如果不匹配,則表空間被標記為丟失。

如果您閱讀了本系列的上一篇文章(MySQL 中的加密:Keystore),那麼您可能還記得,當使用基於服務器的密鑰存儲時,服務器在啟動時僅接收密鑰標識符列表,或者更確切地說,密鑰id 和用戶id,因為這對唯一標識密鑰。 現在我說的是,當服務器啟動時,它會收到檢查它是否可以解密表空間密鑰所需的所有密鑰。 那麼為什麼在初始化時,在服務器存儲的情況下,只加載keyID 和用戶id,而不是所有鍵? 因為您可能不需要所有鑰匙。 這主要是由於主密鑰輪換造成的。 輪換主密鑰時,會在保管庫中創建新的主密鑰,但不會刪除舊密鑰。 因此,服務器密鑰庫中可能有許多服務器不需要的密鑰,因此在服務器啟動時不會檢索這些密鑰。

現在是時候談談主密鑰加密的優點和缺點了。 最大的優點是您只需要一個加密密鑰(主密鑰),該密鑰將與您的加密數據分開存儲。 這使得服務器啟動速度快,存儲空間小,易於管理。 而且單個主密鑰很容易重新生成。

然而,主密鑰加密有一個很大的缺點:一旦使用 tablespace_key 加密表空間,它就始終保持使用相同密鑰的加密狀態。 旋轉主鑰匙在這裡沒有幫助。 為什麼這是一個缺點? 我們知道 MySQL 存在一些錯誤,可能會導致突然崩潰並創建核心文件。 由於核心文件包含服務器內存轉儲,因此轉儲可能包含解密的表空間密鑰。 更糟糕的是,解密的表空間密鑰存儲在內存中,可以交換到磁盤。 您可以說這不是一個缺點,因為您需要 root 權限才能訪問這些文件和交換分區。 是的。 但root只需要一段時間。 一旦某人有權訪問解密的表空間密鑰,即使沒有 root 權限,他/她也可以繼續使用它來解密數據。 此外,磁盤可能被盜,交換分區/核心文件可以使用第三方工具讀取。 TDE 的目標是即使磁盤被盜也無法讀取。 在 用於 MySQL 的 Percona 服務器 可以使用新生成的密鑰重新加密表空間。 此功能稱為加密線程,在撰寫本文時仍處於實驗階段。

了解有關課程的更多信息

閱讀更多:

來源: www.habr.com

添加評論