今天看登录认证,需要指出的是MySQL支持多种登录方式,而且支持SSL,我们只看最简单的,基础流程如下:
Client Server | handshake | |<-------------------| | authentication | |------------------->| | auth result | |<-------------------| | |
1、handshake
格式:(Initial Handshake Packet)
1 [0a] protocol version string[NUL] server version 4 connection id string[8] auth-plugin-data-part-1 1 [00] filler 2 capability flags (lower 2 bytes) if more data in the packet: 1 character set 2 status flags 2 capability flags (upper 2 bytes) if capabilities & CLIENT_PLUGIN_AUTH { 1 length of auth-plugin-data } else { 1 [00] } string[10] reserved (all [00]) if capabilities & CLIENT_SECURE_CONNECTION { string[$len] auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8)) if capabilities & CLIENT_PLUGIN_AUTH { if version >= (5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2) { string[EOF] auth-plugin name } elseif version >= 5.5.10 or >= 5.6.2 { string[NUL] auth-plugin name } }
抓包:
00000000 42 00 00 00 0A 35 2E 31 2E 34 39 2D 63 6F 6D 6D B....5.1 .49-comm 00000010 75 6E 69 74 79 2D 6C 6F 67 00 14 00 00 00 49 69 unity-lo g.....Ii 00000020 57 55 27 5E 26 42 00 FF F7 1C 02 00 00 00 00 00 WU'^&B.. ........ 00000030 00 00 00 00 00 00 00 00 00 5A 7C 24 39 32 2E 2F ........ .Z|$92./ 00000040 43 40 5A 25 46 00 C@Z%F.
解析:
42 00 00 //数据长度,3字节,0x42=66字节 00 //序号,1字节 0A //协议,1字节,0x0A=10,表示第10版协议 35 2E 31 2E 34 39 2D 63 6F 6D 6D 75 6E 69 74 79 2D 6C 6F 67 00 //版本信息,字符串,以\0结尾,内容为5.1.49-community-log 14 00 00 00 //连接ID,4字节,0x14=20 5e 63 59 72 54 2c 7b 4a //加密串的前半部分,定长8字节 00 //固定填充0 FF F7 //服务端属性的低16位,2字节,枚举参见网站 1C //字符集,1字节,0x1c=28=gbk_chinese_ci 02 00 //服务端状态,2字节,枚举参见网站 00 00 //服务端属性的高16位,2字节 00 //固定填充0 00 00 00 00 00 00 00 00 00 00 //固定填充0,10字节 5A 7C 24 39 32 2E 2F 43 40 5A 25 46 00 //加密串的后半部分,以\0结尾,加密串总共8+12=20字节
2、authentication
格式:(Handshake Response Packet)
4 capability flags, CLIENT_PROTOCOL_41 always set 4 max-packet size 1 character set string[23] reserved (all [0]) string[NUL] username if capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA { lenenc-int length of auth-response string[n] auth-response } else if capabilities & CLIENT_SECURE_CONNECTION { 1 length of auth-response string[n] auth-response } else { string[NUL] auth-response } if capabilities & CLIENT_CONNECT_WITH_DB { string[NUL] database } if capabilities & CLIENT_PLUGIN_AUTH { string[NUL] auth plugin name } if capabilities & CLIENT_CONNECT_ATTRS { lenenc-int length of all key-values lenenc-str key lenenc-str value if-more data in 'length of all key-values', more keys and value pairs }
抓包:
00000000 40 00 00 01 8D A6 03 00 FF FF FF 00 21 00 00 00 @....... ....!... 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 00000020 00 00 00 00 74 65 73 74 00 14 B4 2F BB 65 7A D4 ....test .../.ez. 00000030 55 BA 9E E4 4B 34 A3 2C F6 58 92 7A A7 A2 76 6D U...K4., .X.z..vm 00000040 6E 70 6E 00 npn.
解析:
40 00 00 //数据长度,3字节,0x40=64字节 01 //序号,1字节,同一个动作的所有请求与响应会递增此值 8D A6 03 00 //客户端支持的属性,4字节,枚举参见网站 FF FF FF 00 //最大数据包长度,4字节,0xffffff=16777215=约16MB 21 //字符集,1字节,0x21=33=utf8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 //固定填充0,23字节 74 65 73 74 00 //用户名,\0结尾的字符串,内容为test 14 //密码串长度,1字节,0x14=20字节 B4 2F BB 65 7A D4 55 BA 9E E4 4B 34 A3 2C F6 58 92 7A A7 A2 //密码的加密串,20字节(算法见后) 76 6D 6E 70 6E 00 //初始数据库,\0结尾的字符串,内容为vmnpn
加密算法:
SHA1(password) XOR SHA1("20-bytes random data from server" <concat> SHA1(SHA1(password)))
3、auth ok
格式:(OK Packet)
1 [00] the OK header lenenc-int affected rows lenenc-int last-insert-id if capabilities & CLIENT_PROTOCOL_41 { 2 status_flags 2 warnings } elseif capabilities & CLIENT_TRANSACTIONS { 2 status_flags } string[EOF] info
抓包:
00000000 07 00 00 02 00 00 00 02 00 00 00 ........ ........
解析:
07 00 00 //数据长度,3字节,0x07=7字节 02 //序号,1字节,在上一个包的基础上又+1了 00 //状态标识,1字节,0x00表示成功 00 //影响行数,变长数值 00 //LastInsertId,变长数值 02 00 //状态,2字节,枚举参见网站 00 00 //消息
4、auth fail
格式:(ERR Packet)
1 [ff] the ERR header 2 error code if capabilities & CLIENT_PROTOCOL_41 { string[1] '#' the sql-state marker string[5] sql-state } string[EOF] error-message
抓包:
00000000 48 00 00 02 FF 15 04 23 32 38 30 30 30 41 63 63 .......# 28000Acc 00000010 65 73 73 20 64 65 6E 69 65 64 20 66 6F 72 20 75 ess deni ed for u 00000020 73 65 72 20 27 74 65 73 74 27 40 27 54 69 61 6E ser 'tes t'@'Tian 00000030 59 75 2D 50 43 27 20 28 75 73 69 6E 67 20 70 61 Yu-PC' ( using pa 00000040 73 73 77 6F 72 64 3A 20 59 45 53 29 ssword: YES)
解析:
48 00 00 //数据长度,3字节,0x48=72字节 02 //序号,1字节,在上一个包的基础上又+1了 FF //状态标识,1字节,0xff表示错误 15 04 //错误码,2字节,0x415=1045 23 //固定1字节,# 32 38 30 30 30 //SQL状态,固定5字节,内容=28000 41 63 63 65 ... 59 45 53 29 //出错信息,字符串,内容=Access denied for user 'test'@'TianYu-PC' (using password: YES)
未完待续……