MySQL是如何做到安全登陸
首先Mysql的密碼權限存儲在mysql.user表中。我們不關注鑒權的部分,我們只關心身份認證,識別身份,后面的權限控制是很簡單的事情。
在mysql.user表中有個authentication_string字段,存儲的是密碼的兩次sha1值。
你可以用下面的語句,驗證和mysql.user表中存儲的是一致的。
select sha1(UNHEX(sha1(‘password’)))
以上就是服務端關于密碼的存儲,接下來是認證過程。
Mysql采用的是一種challenge/response(挑戰-應答)的認證模式。
***步:客戶端連接服務器
第二步:服務器發送隨機字符串challenge給客戶端
第三步:客戶端發送username+response給服務器
其中response=HEX(SHA1(password) ^ SHA1(challenge + SHA1(SHA1(password))))
第四步:服務器驗證response。
服務器存儲了SHA1(SHA1(password)))
所以可以計算得到SHA1(challenge + SHA1(SHA1(password))))
那么SHA1(password)=response^ SHA1(challenge + SHA1(SHA1(password))))
***再對SHA1(password)求一次sha1和存儲的數據進行比對,一致表示認證成功。
我們分析它的安全性:
- 抓包可以得到response,但是每次認證服務器都會生成challenge,所以通過抓包無法構造登陸信息。
- 數據庫內容被偷窺,數據庫記錄的是sha1(sha1(password)),不可以得到sha1(password)和明文密碼,所以無法構造response,同樣無法登陸。
當然如果被抓包同時數據庫泄密,就可以得到sha1(password),就可以仿冒登陸了。
這種認證方式其實是有一個框架標準的,叫做SASL(Simple Authentication and Security Layer ),專門用于C/S模式下的用戶名密碼認證。原理就是服務器發送一個挑戰字challenge給客戶端,客戶端返回的response證明自己擁有密碼,從而完成認證的過程,整個過程不需要密碼明文在網絡上傳輸。
基于SASL協議有很多實現,mysql的就是模仿的CRAM-MD5協議,再比如SCRAM-SHA1協議,是mongdb、PostgreSQL 使用的認證方式。在JDK中專門有一套SASL的API,用于實現不同的SASL認證方式。