- GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯系小編并注明來源,
- GreatSQL是MySQL的國產分支版本,使用上與MySQL一致,
介紹
從 MySQL 8.0.4 開始,MySQL 默認身份驗證插件從 mysql_native_password 改為 caching_sha2_password ,相應地,libmysqlclient 也使用 caching_sha2_password 作為默認的身份驗證機制,
起因
在這之前 MySQL 5.6/5.7 使用的默認密碼插件是 mysql_native_password,mysql_native_password 的特點是不需要加密的連接,該插件驗證速度特別快,但是不夠安全,因為,mysql_native_password 使用的是于 SHA1 演算法,NIST(美國國家標準與技術研究院)在很早之前就已建議停止使用 SHA1 演算法,因為 SHA1 和其他哈希演算法(例如 MD5)容易被破解,
其實從 MySQL 5.6 開始就引入了更安全的認證機制:ha256_password 認證插件,它使用一個加鹽密碼(salted password)進行多輪 SHA256 哈希(數千輪哈希,暴力破解更難),以確保哈希值轉換更安全,但是,建立安全連接和多輪 hash 加密很耗費時間,雖然安全性更高,但是驗證速度不夠快,
改進
MySQL 試圖結合倆者的優點,于是在 MySQL-8.0.3 引入了一個新的身份驗證插件 caching_sha2_password ,作為sha256_password的代替方案,在sha256_password 的基礎上進行了改進補上了短板,既解決安全性問題又解決性能問題,與此同時 sha256_password將退出時代的浪潮,MySQL 預計在未來版本中將其洗掉,使用 sha256_password 進行身份驗證的 MySQL 帳戶建議轉為 caching_sha2_password,
結果
因為默認身份驗證機制的更改,大家在使用 MySQL 8.0 時候出現了很多相關的問題,網上的大部分教程都是教人改回mysql_native_password驗證方式 mysql_native_password,但是筆者認為,MySQL 更改默認插件是為了更好的安全性考慮,如果有 MySQL 服務要公網上使用,建議還是盡量使用 caching_sha2_password作為認證插件,
示例:使用舊版本客戶端連接時報錯:
shell> mysql -uroot -p
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded
具體機制分析
mysql_native_password
mysql_native_password 作為 MySQL 5.6/5.7 的默認密碼插件 ,其優點是它支持 challenge-response (挑戰應答方式),這是非常快的驗證機制,無需在網路中發送實際密碼,并且不需要加密的連接,
客戶端連接MySQL實體時,首先需要從服務器端獲得一個20位元組的亂數,
此外,mysql_native_password 使用了新的哈希演算法進行認證校驗,對于用戶的原始密碼,通過SHA1(SHA1(password))兩次哈希計算結果保存在 mysql.user 表的 authentication_string 列中,其中用戶密碼通過哈希計算后保存,沒有加鹽(salt),
通過上述這樣的處理,MySQL資料庫本身已然非常安全,然而,隨著時間的推移,目前存在以下兩種潛在風險:
- SHA1哈希演算法也已經變得比較容易破解,
- 相同的密碼擁有相同的哈希值,
SHA1、MD5等之前的哈希演算法都已然不再安全,更為安全的SHA256、SHA512哈希演算法也已推出,作為資料存盤最終承載者,應該使用更新的加密機制機制,
caching_sha2_password
在cache_sha2_password密碼認證機制下,其改進如下所示:
- 保存在
authentication_string中的哈希值為加鹽后的值,即使兩個不同用戶的密碼相同,保存在計算機中的哈希值也不同, - 哈希演算法升級為了更為安全SHA256演算法,
- 哈希演算法的
round次數從原來的兩次,提升為了5000次,round次數越多,每次計算哈希值的代價越大,破解難度也就越大, - 用TLS的加密或RSA密鑰傳輸方式從客戶端將密碼傳送到服務端,
通訊程序決議
- 對于大多數連接嘗試,當密碼的哈希值有快取在記憶體中時,它的驗證是基于 SHA256 的
challenge-response機制(與mysql_native_password中基于 SHA1 的challenge-response機制相比更快),下圖演示了在有哈希快取時的驗證流程,

- 客戶端連接服務端
- 服務端給客戶端發送 Nonce(20 位元組長的隨機資料)
- 客戶端使用 XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce)) 生成 Scramble 發送給服務端
- 服務端檢查 username/SHA256(SHA256(user_password)) 是否在記憶體快取條目中存在,存在則證明合法;發送 fast_auth_success 包到客戶端
- 服務端發送 OK 包到客戶端
- 進入命令階段
Nonce 是一個在加密通信只能使用一次的數字,在認證協議中,它往往是一個隨機或偽亂數(salt),以避免暴力攻擊,
- 當沒有這種快取時,
caching_sha2_password需要使用安全連接進行密碼交換,考慮到用戶更改和FLUSH PRIVILEGES操作頻率比較低,所以在大多數情況下,使用的都是基于challenge-response的身份驗證,不用建立安全連接,這省去了建立安全連接需要耗費的資源,下圖總結了完整的驗證流程,

- 客戶端連接服務端
- 服務端給客戶端發送 Nonce(20 位元組長的隨機資料)
- 客戶端使用 XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce)) 生成 Scramble 發送給服務端
- 服務端檢查 username/SHA256(SHA256(user_password)) 是否在記憶體快取條目中存在,不存在則發送 perform_full_authentication 包到客戶端繼續認證
- 客戶端收到 perform_full_authentication 包,可以進行如下處理
- 如果安全連接已經建立基于 ,則可以直接發送明文密碼到服務端
向服務端發起獲取公鑰的請求(或者指定服務端公鑰檔案),使用公鑰+Nonce加密密碼,發送加密后的密碼到服務端
服務器通過 SHA256 演算法計算得到哈希值,判斷是否用戶認證通過,通過則發送 OK 包到客戶端 - 進入命令階段
這里詳細解釋一下 RSA 非對稱加密的通信程序:
首先先明確一個概念:非對稱加密演算法中,有兩個密鑰:公鑰和私鑰,如果用公鑰進行加密,只有對應的私鑰才能解密;反之亦然,
RSA 密鑰交換程序:
服務器生成一對密鑰并將公鑰向其他方公開(明文發送給客戶端);
客戶端使用服務器的公鑰對密碼進行加密后發送給服務器;
服務器用對應的私鑰對加密資訊進行解密,
因為客戶端用公鑰加密的資訊只能用服務器的私鑰解密,所以這個連接程序可以視為加密通信,

需要注意的地方
默認身份驗證插件的更改意味著:
在 MySQL 8.0.4 之后創建的所有新用戶將默認使用 caching_sha2_password 作為身份驗證插件,
mysql> SELECT USER,PLUGIN FROM mysql.`user` ;
+------------------+-----------------------+
| USER | PLUGIN |
+------------------+-----------------------+
| root | caching_sha2_password |
| mysql.infoschema | caching_sha2_password |
| mysql.session | caching_sha2_password |
| mysql.sys | caching_sha2_password |
+------------------+-----------------------+
6 rows in set (0.06 sec)
libmysqlclient 默認使用 caching_sha2_password,可以通過手動修改切換到其他的身份驗證插件,
對于使用 caching_sha2_password 插件的客戶端,連接到服務器時,密碼不會暴露為明文,密碼傳輸是如何進行的取決于是否使用安全連接或 RSA 對密碼加密:
- 如果連接是安全的,可以不使用 RSA 密鑰,適用于使用 TLS 加密的 TCP 連接,以及 Unix 套接字檔案和共享記憶體連接,密碼以明文格式發送,但不能被竊聽,因為連接是安全的,
- 如果連接不是安全的,可以使用 RSA 密鑰對,適用于未使用 TLS 加密的 TCP 連接和 named-pipe 連接,RSA 僅用于客戶端和服務器之間的密碼交換,防止密碼被截取,當服務器接收到使用公鑰加密的密碼后,它使用私鑰解密,一個隨機字串用在加密中,防止重放攻擊(repeat attacks),
在 MySQL 8.0.3 以上版本中,默認自動完成 RSA 密鑰對進行密碼交換,
關于主從復制
復制本身是支持加密的連接,在 MySQL 8.0.4中,添加了復制對 RSA 加密的支持,
如果用于復制的用戶使用了 caching_sha2_password身份驗證插件,并且沒有啟用安全連接( 在group_replication_recovery 啟用SSL支持),MySQL 將使用 RSA 密鑰對進行密碼的交換,可以把主節點的公鑰手動拷貝到從節點的服務器中,也可以設定成:自動為請求加入組的節點提供公鑰,
-
CHANGE MASTER可以通過以下倆個引數來啟用基于caching_sha2_passwordRSA 密鑰來交換密碼:指定 RSA 公鑰路徑 - MASTER_PUBLIC_KEY_PATH ="key_file_path" #從服務端獲取 RSA 公鑰 - GET_MASTER_PUBLIC_KEY = {0 | 1} -
Group Replication 可以通過以下倆個引數來啟用基于
caching_sha2_passwordRSA 密鑰來交換密碼:#指定 RSA 公鑰路徑 ––group-replication-recovery-public-key-path #從服務端獲取 RSA 公鑰 ––group-replication-recovery-get-public-key
資料庫升級
資料庫升級到 MySQL 8.0.4 會怎樣?
在升級之前創建的用戶,身份認證插件不會更改,在升級之后創建的用戶默認使用 aching_sha2_password身份驗證插件,除非使用 --default-authentication-plugin 手動指定認證插件插件,因為不會更改升級前已有用戶,因此,使用升級后依然可以用舊版本的客戶端連接這些用戶,
相應地,libmysqlclient 支持 mysql_options() C API函式的 MYSQL_DEFAULT_AUTH 選項,(對于 MySQL 包中可用的基于 libmysqlclient 的客戶端工具,可以用 ––default-auth 命令列選項達到相同的目的,)
建議使用 cache_sha2_password 因為它更安全,并且升級 libmysqlclient 到 MySQL 8.0.4 或更高版本,以便支持新的身份驗證插件,
參考資料
MySQL 8.0.4 : New Default Authentication Plugin : caching_sha2_password
得物技術淺談MySQL 8.0:新的身份驗證插件
MySQL 8.0密碼認證機制升級,不知道可能導致業務不可用!!!
組復制安裝部署 | 全方位認識 MySQL 8.0 Group Replication
Enjoy GreatSQL ??
關于 GreatSQL
GreatSQL是由萬里資料庫維護的MySQL分支,專注于提升MGR可靠性及性能,支持InnoDB并行查詢特性,是適用于金融級應用的MySQL分支版本,
相關鏈接: GreatSQL社區 Gitee GitHub Bilibili
GreatSQL社區:
捉蟲活動詳情:https://greatsql.cn/thread-97-1-1.html
社區博客有獎征稿詳情:https://greatsql.cn/thread-100-1-1.html

技術交流群:
微信:掃碼添加
GreatSQL社區助手微信好友,發送驗證資訊加群,
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/526034.html
標籤:MySQL
下一篇:mysql資料庫常用命令
