php mysql 加密解密_php一步一步实现mysql协议(三) ——登录认证密码加密

登陆认证阶段

e04a722a8b25e9aacef4a1cd4ae45a5b.png

认证阶段抓包如上图,和初始化握手一样,前四个字节属于消息头,后面的部分属于消息体 。报文的结构图如下:

b7ab5d2c4076396869c27ca7241caf50.png

这里主要设置 用户名 密码 和数据库名这三个参数,其他的使用抓包的默认值即可。用户名和数据库名直接将字符转为十六进制就可以,唯一需要注意的是密码加密部分

官网提供的加密规则如下

SHA1( password ) XOR SHA1( "20-bytes random data from server" SHA1( SHA1( password ) ) )

实现代码如下:

{$pass1 = getBytes(sha1($pass, true));$pass2 = sha1(getString($pass1), true);$pass3 = getBytes(sha1(hexToStr($seed) . $pass2, true));$result = "";for ($i = 0, $count = count($pass3); $i < $count; ++$i) {$result .= str_pad(dechex(($pass3[$i] ^ $pass1[$i])),2,0,STR_PAD_LEFT);

}return $result;

}function getBytes($data)

{$bytes =[];$count = strlen($data);for ($i = 0; $i < $count; ++$i) {$byte = ord($data[$i]);$bytes[] = $byte;

}return $bytes;

}function getString(array $bytes)

{return implode(array_map('chr', $bytes));

}function hexToStr($hex_str){$send_msg = "";foreach (str_split($hex_str,2) as $key => $value) {$send_msg .= chr(hexdec($value));

}return $send_msg;

}

我们从抓包记录中验证一下代码的正确性,在初始化握手包中获取两个salt的值 “1c171e1765783a57” 和 “50185b5a250f323d63394279”

92b01b91f0783c5c3e7ef10f420771ba.png

5a6f207f2440310c271cf70a17b87d0c.png

执行代码获取加密结果

生成的结果与抓包获取的结果一致

356dade7b7d39010570760209b1eb419.png

客户端向服务端发起认证请求后,服务端响应的情况分以下几种:

当客户端发起认证请求或命令请求后,服务器会返回相应的执行结果给客户端。客户端在收到响应报文后,需要首先检查第1个字节的值,来区分响应报文的类型。

响应报文类型第1个字节取值范围

OK 响应报文

0x00

Error 响应报文

0xFF

Result Set 报文

0x01 - 0xFA

Field 报文

0x01 - 0xFA

Row Data 报文

0x01 - 0xFA

EOF 报文

0xFE

注:响应报文的第1个字节在不同类型中含义不同,比如在OK报文中,该字节并没有实际意义,值恒为0x00;而在Result Set报文中,该字节又是长度编码的二进制数据结构(Length Coded Binary)中的第1字节。

代码分享地址

https://github.com/gphper/PHPMysql

参考文档:

https://dev.mysql.com/doc/internals/en/client-server-protocol.html

https://www.cnblogs.com/davygeek/p/5647175.html

https://github.com/louislivi/SMProxy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值