MySQL:密码加密方式
我们先来看一下mysql的加密方式:
mysql> select password('abc');
+-------------------------------------------+
| password('abc') |
+-------------------------------------------+
| *0D3CED9BEC10A777AEC23CCC353A8C08A633045E |
+-------------------------------------------+
mysql> select sha1('abc');
+------------------------------------------+
| sha1('abc') |
+------------------------------------------+
| a9993e364706816aba3e25717850c26c9cd0d89d |
+------------------------------------------+
mysql> select sha1(0xa9993e364706816aba3e25717850c26c9cd0d89d);
+--------------------------------------------------+
| sha1(0xa9993e364706816aba3e25717850c26c9cd0d89d) |
+--------------------------------------------------+
| 0d3ced9bec10a777aec23ccc353a8c08a633045e |
+--------------------------------------------------+
-- 或者直接用复合函数模拟:
mysql> select upper(sha1(unhex(sha1('abc'))));
+------------------------------------------+
| upper(sha1(unhex(sha1('abc')))) |
+------------------------------------------+
| 0D3CED9BEC10A777AEC23CCC353A8C08A633045E |
+------------------------------------------+
讲下hex和unhex两个函数:
hex的输出是字符串,是输入内容的16进制字符串表示形式(如字符串"0A"是16进制数0xA的表示形式)。
mysql> select hex(10); --输入内容是10,输出是10的16进制字符串:"A"
+---------+
| hex(10) |
+---------+
| A |
+---------+
mysql> select hex('10'); --字符串'10'在内存中就是:0x31,0x30(从低地址到高地址,共两个字节),hex输出为字符串'3130'
+-----------+
| hex('10') |
+-----------+
| 3130 |
+-----------+
unhex正相反,输入是字符串,输出是十六进制数。
mysql> select unhex('31'); --字符串"31"经过unhex函数会输出数字0x31,0x31打印到mysql shell上显示为字符'1'
+-------------+
| unhex('31') |
+-------------+
| 1 |
+-------------+
mysql> select unhex(0x3331); --16进制数0x3331实际上是字符串"31",原理同上。
+---------------+
| unhex(0x3331) |
+---------------+
| 1 |
+---------------+
sha1函数的输出是一个字符串(实际上是一个160(2进制)位数的16进制字符串表示形式),unhex将这个字符串转为其实际的数字(也就是那个160位2进制数),然后对这个数再次做sha1哈希运算,得到的字符串就是mysql密码加密后的密文。
再看一下我们用shell怎么模拟mysql对密码加密的过程:
[root@ambari dir]# echo -n "abc" | sha1sum
a9993e364706816aba3e25717850c26c9cd0d89d -
[root@ambari dir]# echo -n "a9993e364706816aba3e25717850c26c9cd0d89d" | xxd -r -ps | sha1sum
0d3ced9bec10a777aec23ccc353a8c08a633045e -
xxd命令是查看二进制文件的,详细使用请参考shell命令的笔记。
如何找出mysql密码:
mysql> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
/var/lib/mysql 目录就是mysql数据文件的存储目录,其中一个数据库对应一个子文件夹,数据库文件夹里有很多文件,3个文件对应本数据库下面的一张表。
如mysql.user表对应的数据文件为:
[root@ambari dir]# ll -h /var/lib/mysql/mysql/user.*
-rw-rw----. 1 mysql mysql 11K 4月 26 14:16 /var/lib/mysql/mysql/user.frm #表结构文件
-rw-rw----. 1 mysql mysql 1004 4月 27 11:06 /var/lib/mysql/mysql/user.MYD #表数据文件
-rw-rw----. 1 mysql mysql 2.0K 5月 2 09:51 /var/lib/mysql/mysql/user.MYI #表索引等信息文件
可以查看二进制数据文件(user.MYD)获取mysql的用户和加密后的密码:
[root@ambari dir]# xxd /var/lib/mysql/mysql/user.MYD
0000000: 0500 7000 3f00 0000 0000 0001 7cfb 0ffc ..p.?.......|...
0000010: 096c 6f63 616c 686f 7374 0472 6f6f 742a .localhost.root*
0000020: 4444 3141 4343 3539 3346 3438 4443 3935 DD1ACC593F48DC95
0000030: 3932 3130 4138 4135 3234 3735 3838 3739 9210A8A524758879
0000040: 4232 4244 4134 4530 0202 0202 0500 7800 B2BDA4E0......x.
0000050: 4700 0000 0000 0001 34fb 0ffc 1161 6d62 G.......4....amb
0000060: 6172 692e 6d61 7374 6572 2e63 6f6d 0472 ari.master.com.r
0000070: 6f6f 742a 4444 3141 4343 3539 3346 3438 oot*DD1ACC593F48
0000080: 4443 3935 3932 3130 4138 4135 3234 3735 DC959210A8A52475
0000090: 3838 3739 4232 4244 4134 4530 0202 0202 8879B2BDA4E0....
00000a0: 0500 7000 3f00 0000 0000 0002 a8fb 0ffc ..p.?...........
00000b0: 0931 3237 2e30 2e30 2e31 0472 6f6f 742a .127.0.0.1.root*
00000c0: 4444 3141 4343 3539 3346 3438 4443 3935 DD1ACC593F48DC95
00000d0: 3932 3130 4138 4135 3234 3735 3838 3739 9210A8A524758879
00000e0: 4232 4244 4134 4530 0202 0202 0500 6a00 B2BDA4E0......j.
...省略n行...
可以用上面的mysql对用户密码的加密算法建立彩虹表,然后破解mysql用户的密码。