關於 MySQL 密碼你應該知道的那些事
本文將介紹MySQL使用者密碼相關的一些知識,以及5.6中對於安全性的一些改進
MySQL使用者密碼是如何產生和儲存的
如果你已經接觸MySQL一段時間了,那麼想必你一定知道MySQL把所有使用者的使用者名稱和密碼的密文存放在mysql.user
表中。大致的形式如下:
mysql [localhost]{msandbox}(mysql)>select user,password from mysql.user;
+----------------+-------------------------------------------+
| user | password |
+----------------+-------------------------------------------+
| root |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| plain_password |*861D75A7F79DE84B116074893BBBA7C4F19C14FA|
| msandbox |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| msandbox |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| msandbox_rw |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| msandbox_rw |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| msandbox_ro |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| msandbox_ro |*6C387FC3893DBA1E3BA155E74754DA6682D04747|
| rsandbox |*B07EB15A2E7BD9620DAE47B194D5B9DBA14377AD |
+----------------+-------------------------------------------+
9 rows inset(0.01 sec)*
可見MySQL在其內部是不存放使用者的純文字密碼的(這個也是一般程式對于敏感資訊的最基礎保護)。一般來說密文是通過無法復原密碼編譯演算法得到的。這樣即使敏感資訊洩漏,除了暴力破解是無法快速從密文直接得到明文的。
MySQL用的是哪種無法復原演算法來加密使用者密碼的
MySQL實際上是使用了兩次SHA1夾雜一次unhex的方式對使用者密碼進行了加密。具體的演算法可以用公式表示:password_str = concat('*', sha1(unhex(sha1(password))))
我們可以用下面的方法做個簡單的驗證。
mysql [localhost]{msandbox}(mysql)>select password('mypassword'),concat('*',sha1(unhex(sha1('mypassword'))));
+-------------------------------------------+---------------------------------------------+
| password('mypassword')| concat('*',sha1(unhex(sha1('mypassword'))))|
+-------------------------------------------+---------------------------------------------+
|*FABE5482D5AADF36D028AC443D117BE1180B9725 |*fabe5482d5aadf36d028ac443d117be1180b9725 |
+-------------------------------------------+---------------------------------------------+
1 row inset(0.01 sec)
MySQL使用者密碼的不安全性
其實MySQL在5.6版本以前,對於對於安全性的重視度非常低,對於使用者密碼也不例外。例如,MySQL對於binary log中和使用者密碼相關的操作是不加密的。如果你向MySQL發送了例如create user
,grant user ... identified by
這樣的攜帶初始純文字密碼的指令,那麼會在binary log中原原本本的被還原出來。我們通過下面的例子來驗證。
建立一個使用者:
mysql [localhost]{msandbox}(mysql)> create user plain_password identified by'plain_pass';
Query OK,0 rows affected (0.00 sec)
用mysqlbinlog查看二進位日誌:
shell> mysqlbinlog binlog.000001
# at 106
#150227 23:37:59 server id 1 end_log_pos 223 Query thread_id=1 exec_time=0 error_code=0
use mysql/*!*/;
SET TIMESTAMP=1425051479/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1,@@session.sql_auto_is_null=1,@@session.unique_checks=1,@@session.autocommit=1/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1,@@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create user plain_password identified by'plain_pass'
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
MySQL5.6中對於使用者密碼的安全性加強
好在MySQL5.6開始對安全性有了一定的重視,為了杜絕純文字密碼出現在binlog中的情況,MySQL引入了一系列會以密文方式記錄二進位日誌的命令:
- CREATE USER … IDENTIFIED BY …
- GRANT … IDENTIFIED BY …
- SET PASSWORD …
- SLAVE START … PASSWORD = … (as of 5.6.4)
- CREATE SERVER … OPTIONS(… PASSWORD …) (as of 5.6.9)
- ALTER SERVER … OPTIONS(… PASSWORD …) (as of 5.6.9)
細心你的也許會發現,change master to master_password=''
命令不在這個範疇中。這也就意味著MySQL5.6中仍然使用這樣的文法來啟動replication時有安全風險的。這也就是為什麼5.6中使用帶有純文字密碼的change master to
時會有warning提示,具體如下:
slave1 [localhost]{msandbox}((none))> change master to master_host='127.0.0.1',master_port =21288,master_user='rsandbox',master_password='rsandbox',master_auto_position=1;
Query OK,0 rows affected,2 warnings (0.04 sec)
slave1 [localhost]{msandbox}((none))> show warnings;
+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|Level|Code|Message|
+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|Note|1759|Sending passwords in plain text without SSL/TLS is extremely insecure.|
|Note|1760|StoringMySQL user name or password information in the master info repository isnot secure andis therefore not recommended.Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax'in the MySQLManualfor more information.|
+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows inset(0.00 sec)
本文永久更新連結地址: