本文將介紹MySQL用戶密碼相關的一些知識,以及5.6中對於安全性的一些改進mysql
http://cenalulu.github.io/mysql/myall-about-mysql-password/github
若是你已經接觸MySQL一段時間了,那麼想必你必定知道MySQL把全部用戶的用戶名和密碼的密文存放在mysql.user
表中。大體的形式以下:
{% highlight mysql %}
{% raw %}
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 in set (0.01 sec)
{% endraw %}
{% endhighlight %}算法
可見MySQL在其內部是不存放用戶的明文密碼的(這個也是通常程序對於敏感信息的最基礎保護)。通常來講密文是經過不可逆加密算法獲得的。這樣即便敏感信息泄漏,除了暴力破解是沒法快速從密文直接獲得明文的。sql
MySQL其實是使用了兩次SHA1夾雜一次unhex的方式對用戶密碼進行了加密。具體的算法能夠用公式表示:password_str = concat('*', sha1(unhex(sha1(password))))
咱們能夠用下面的方法作個簡單的驗證。
{% highlight mysql %}
{% raw %}
mysql [localhost] {msandbox} (mysql) > select password('mypassword'),concat('',sha1(unhex(sha1('mypassword'))));
+-------------------------------------------+---------------------------------------------+
| password('mypassword') | concat('',sha1(unhex(sha1('mypassword')))) |
+-------------------------------------------+---------------------------------------------+
| FABE5482D5AADF36D028AC443D117BE1180B9725 | fabe5482d5aadf36d028ac443d117be1180b9725 |
+-------------------------------------------+---------------------------------------------+
1 row in set (0.01 sec)
{% endraw %}
{% endhighlight %}shell
其實MySQL在5.6版本之前,對於對於安全性的重視度很是低,對於用戶密碼也不例外。例如,MySQL對於binary log中和用戶密碼相關的操做是不加密的。若是你向MySQL發送了例如create user
,grant user ... identified by
這樣的攜帶初始明文密碼的指令,那麼會在binary log中原本來本的被還原出來。咱們經過下面的例子來驗證安全
建立一個用戶
{% highlight mysql %}
{% raw %}
mysql [localhost] {msandbox} (mysql) > create user plain_password identified by 'plain_pass';
Query OK, 0 rows affected (0.00 sec)
{% endraw %}
{% endhighlight %}bash
用mysqlbinlog查看二進制日誌
{% highlight bash %}
{% raw %}
shell> mysqlbinlog binlog.000001session
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 ;ide
ROLLBACK /* added by mysqlbinlog /;
/!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
{% endraw %}
{% endhighlight %}
好在MySQL5.6開始對安全性有了必定的重視,爲了杜絕明文密碼出如今binlog中的狀況,MySQL引入了一系列會以密文方式記錄二進制日誌的命令:
細心你的也許會發現,change master to master_password=''
命令不在這個範疇中。這也就意味着MySQL5.6中仍然使用這樣的語法來啓動replication時有安全風險的。這也就是爲何5.6中使用帶有明文密碼的change master to
時會有warning提示,具體以下:
{% highlight mysql %}
{% raw %}
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 | Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. |
+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
{% endraw %}
{% endhighlight %}
reference:
http://www.pythian.com/blog/hashing-algorithm-in-mysql-password-2/