top
Loading...
5.7.9.MySQL4.1中的密碼哈希處理
5.7.9. MySQL 4.1中的密碼哈希處理
5.7.9.1. 更改應用程序密碼哈希值的含義

MySQL用戶賬戶列于mysql數據庫中的user表內。每個MySQL賬戶指定一個密碼,盡管保存在userPassword列的密碼不是明文,但哈希值是從表中的記錄計算的。用PASSWORD()函數來計算密碼的哈希值。

MySQL在客戶端/服務器通信的兩個階段使用密碼:

·         如果客戶端試圖連接服務器,有一個初始鑒定步驟,客戶必須提供一個密碼,并且必須與客戶想要使用的賬戶在user表保存的哈希值匹配。

·         客戶端連接后,它可以(如果有充分的權限) 設置或更改user表內所列的賬戶的密碼哈希值值。客戶端可以通過PASSWORD()函數來生成密碼哈希值,或使用GRANTSET PASSWORD語句。

換句話說,當客戶端首次試圖連接時,服務器使用哈希值進行鑒定。如果連接的客戶端調用PASSWORD()函數或使用GRANTSET語句來設置或更改密碼,則服務器產生哈希值。

MySQL 4.1中密碼哈希算法已經更新,提供了更好的安全性并降低了密碼被截取的風險。但是,該新機制只能在MySQL 4.1(和更新版本的)服務器和客戶端中使用,會產生一些兼容性問題。4.1或新客戶端可以連接4.1之前的服務器,因為客戶端可以同時理解舊的和新的密碼哈希機制。但是,4.1之前的客戶端試圖連接4.1版或更新版的服務器時會遇到困難。例如,3.23mysql客戶端試圖連接5.1服務器時會失敗并出現下面的錯誤消息:

shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

出現該問題的另一個普通例子是在升級到MySQL 4.1或更新版后,試圖使用舊版本的PHP mysql擴展名。(參見25.3.1節,“使用MySQL和PHP的常見問題”)

下面討論了新、舊密碼機制之間的差別,以及如果你升級了服務器但需要為4.1版以前的客戶端保持向后兼容性該怎樣做。A.2.3節,“客戶端不支持鑒定協議”中有更詳細的信息。該信息將MySQL數據庫從4.0版本或更低版升級到4.1版或更高版的PHP編程人員特別重要。

釋:該討論對比了4.1版的行為和4.1前的行為,這兒描述的4.1中的行為實際上從4.1.1開始。MySQL 4.1.0是一個“舊”的發布,因為它的實施機制與4.1.1版和更新版中的稍有不同。在MySQL 5.0 參考手冊中詳細描述了4.1.0和最新版之間的差別。

MySQL 4.1之前,PASSWORD()函數計算的密碼哈希值有16個字節長。應為:

mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e   |
+--------------------+

MySQL 4.1之前,user表的Password(保存了哈希值)也是16字節長。

MySQL 4.1,已經對PASSWORD()函數進行了修改,可以生成41字節的哈希值:

mysql> SELECT PASSWORD('mypass');
+-------------------------------------------+
| PASSWORD('mypass')                        |
+-------------------------------------------+
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
+-------------------------------------------+

同樣,user表的Password列必須有41字節長來保存這些值:

·         如果你新安裝MySQL 5.1, Password列自動為41字節長。

·         MySQL 4.1(4.1.14.1系列的更新版)升級到MySQL 5.1,應不會出現相關問題,因為兩個版本使用相同的密碼哈希機制。如果你想要將更早版本的MySQL升級到MySQL5.1,你應先升級到4.1,然后將4.1升級到5.1

加寬的Password列可以同時保存新、舊格式的密碼哈希值。可以有兩種方式確定任何給定格式的密碼哈希值:

·         明顯的不同之處是長度(16字節和41字節)

·         2個不同之處是新格式的密碼哈希值都以‘*’字符開頭,而舊格式的密碼絕對不是。

 長密碼哈希值具有更好的加密屬性,并且客戶端根據長哈希值進行鑒定比舊的短哈希值更加安全。

短密碼哈希值和長密碼哈希值之間的不同之處與服務器如何使用密碼進行鑒定以及如何為執行密碼更改操作的連接的客戶端生成密碼哈希值都有關。

服務器使用密碼哈希值進行鑒定的方式受Password列的寬度影響:

·         如果列較短,只用短哈希鑒定。

·         如果列較長,可以有短或長哈希值,并且服務器可以使用任何一種格式:

o        4.1之前的客戶端可以連接,它們只可以使用舊的哈希機制,它們可以只鑒定有短哈希的賬戶。

o        4.1及以后版本的客戶端可以鑒定有短哈希或長哈希的賬戶。

對于短哈希賬戶的鑒定過程,4.1和以后版本的客戶端比為舊版本的客戶端實際要安全得多。從安全性角度,從最低安全到最安全的梯度為:

·         4.1之前的客戶端用短密碼哈希值進行鑒定

·         4.1或以后版本的客戶端用短密碼哈希值進行鑒定

·         4.1或以后版本的客戶端用長密碼哈希值進行鑒定

服務器為連接的客戶端生成密碼哈希值的方式受Password列寬度和--old-passwords選項的影響。4.1或更新版本的服務器只有滿足某個條件才生成長哈希:Password列必須足夠寬以容納長哈希值并且未給定--old-passwords選項。這些條件適合:

·         Password列必須足夠寬以容納長哈希(41字節)值。如果列沒有更新,仍然為4.1之前的16字節寬,當客戶端使用PASSWORD()GRANTSET PASSWORD執行密碼更改操作時,服務器注意到長哈希不適合,只生成短哈希。如果你已經升級到4.1但還沒有運行 mysql_fix_privilege_tables腳本來擴寬Password列時會出現這種行為。

·         如果Password列足夠寬,則可以保存短或長密碼哈希值。在這種情況下,PASSWORD()GRANTSET PASSWORD生成長哈希,除非 用--old-passwords選項啟動服務器。該選項強制服務器生成短密碼哈希值。

--old-passwords選項的目的是當服務器生成長密碼哈希值時,允許你維持同4.1之前的客戶端的向后兼容性。該選項不影響鑒定(4.1和以后版本的客戶端仍然可以使用有長密碼哈希值的賬戶),但它防止在密碼更改操作中在user表中創建長密碼哈希值。在這種情況下,該賬戶不能再用于4.1之前的客戶端。沒有--old-passwords選項,可能會出現下面的不期望的情況:

·         舊客戶端連接有短密碼哈希值的賬戶。

·         客戶更改自己的密碼。沒有--old-passwords,可以為該賬戶生成長密碼哈希值。

·         下次舊客戶試圖連接賬戶時不能連接上,因為賬戶有長密碼哈希值,需要新的哈希機制進行鑒定。(一旦賬戶user表中為長密碼哈希值,只有4.1和以后版本的客戶端可以鑒定它,因為4.1之前的客戶端不理解長哈希)

該場景說明,如果你必須支持舊的4.1之前的客戶端,不使用--old-passwords選項運行4.1或更新版本的服務器很危險。用--old-passwords運行服務器,密碼更改操作不會生成長密碼哈希值,這樣舊客戶端也可以訪問賬戶。(這些客戶端不能意外地因更改了密碼將自己鎖出去,并留下長密碼哈希值)

--old-passwords選項的不利之處是你創建或更改的密碼使用短哈希,甚至對于4.1客戶端也如此。這樣,你丟失了長密碼哈希值提供的安全性。如果你想要創建有長哈希的賬戶(例如,為4.1客戶端),你必須不使用--old-passwords來運行服務器。

下面的場景可用于運行4.1或以后的服務器,包括MySQL 5.1

場景1user表中的短Password列:

·         只有短哈希可以保存到Password列。

·         服務器只使用短哈希進行客戶端鑒定。

·         對于連接的客戶端,調用PASSWORD()GRANTSET PASSWORD的密碼哈希生成操作專使用短哈希。對賬戶的任何更改均會生成短密碼哈希值。

·          --old-passwords選項可以使用但是多余,因為Password列較短,服務器只生成短密碼哈希值。

場景2Password列;沒有用--old-passwords選項啟動服務器:

·         短或長哈希可以保存到Password列。

·         4.1和以后版本的客戶端(包括5.1客戶端)可以鑒定有短或長哈希的賬戶。

·         4.1之前的客戶端只能鑒定有短哈希的賬戶。

·         對于連接的客戶端,調用PASSWORD()GRANTSET PASSWORD的密碼哈希生成操作專使用短哈希。對賬戶的任何更改均會生成短密碼哈希值。

如前面所示,該場景的危險性在于4.1之前的客戶端可能不能訪問有短密碼哈希值的賬戶。通過PASSWORD()GRANTSET PASSWORDA對這些賬戶密碼的更改會產生長的密碼哈希值。從該點看,4.1之前的客戶端升級到4.1之前不能鑒定該賬戶。

要處理該問題,可以用特殊方法更改密碼。例如,一般情況你可以使用SET PASSWORD按照下面的方法更改賬戶密碼:

mysql> SET PASSWORD FOR 'some_user'@'some_host' = PASSWORD('mypass');

要想更改密碼但創建短哈希,使用OLD_PASSWORD()函數:

mysql> SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('mypass');

當你想明顯生成短哈希時OLD_PASSWORD()很有用。

場景3Password列;用--old-passwords選項啟動4.1或新版本的服務器:

·         短或長哈希可以保存到Password列。

·         4.1和以后版本的客戶端可以鑒定有短或長哈希的賬戶(請注意只有不使用--old-passwords選項啟動服務器,方可以創建長哈希)

·         4.1之前的客戶端只可以鑒定短哈希賬戶。

·         對于連接的客戶端,調用PASSWORD()GRANTSET PASSWORD的密碼哈希生成操作專使用短哈希。對賬戶的任何更改均會生成短密碼哈希值。

在該場景中,你不能創建長密碼哈希值的賬戶,因為--old-passwords選項防止生成長哈希。并且,如果你在使用--old-passwords選項前創建長哈希賬戶,當--old-passwords有時更改賬戶密碼,結果會使賬戶的密碼為短密碼,安全性較長哈希要降低。

這些場景的不利之處可以概括為:

在場景1,你不能利用長哈希提供更安全的鑒定。

在場景2, 如果你沒有顯式使用OLD_PASSWORD()來更改密碼,則4.1之前的客戶端不能再訪問短哈希賬戶。

在場景3,--old-passwords防止短哈希賬戶不可訪問,但密碼更改操作使賬戶的長哈希轉換為短哈希,當--old-passwords有效時不能將它改回長哈希。

作者:mysql.com
來源:http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html
北斗有巢氏 有巢氏北斗