php一步一步实现mysql协议(三) ——登录认证密码加密
登陆认证阶段
认证阶段抓包如上图,和初始化握手一样,前四个字节属于消息头,后面的部分属于消息体 。报文的结构图如下:
这里主要设置 用户名 密码 和数据库名这三个参数,其他的使用抓包的默认值即可。用户名和数据库名直接将字符转为十六进制就可以,唯一需要注意的是密码加密部分
官网提供的加密规则如下
SHA1( password ) XOR SHA1( "20-bytes random data from server" <concat> SHA1( SHA1( password ) ) )
实现代码如下:
<?php
function encryptionPass($pass, $seed)
{
$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”
执行代码获取加密结果
<?php
$salt1 = "1c171e1765783a57";
$salt2 = "50185b5a250f323d63394279";
echo encryptionPass("123456",$salt1.$salt2);
//生成结果:"a1b247e81adf52e0700e31698960ad96271b34f5"
生成的结果与抓包获取的结果一致
客户端向服务端发起认证请求后,服务端响应的情况分以下几种:
当客户端发起认证请求或命令请求后,服务器会返回相应的执行结果给客户端。客户端在收到响应报文后,需要首先检查第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
- 19条运营线路,北京地铁如何进行智能化运维?
- 未来二十年,产业变革的核心是什么?
- 大数据助你购买航空延误险,飞机延误未必是坏事!
- 作为一个有追求的程序员,你应该掌握的七种武器
- 腾讯云直播答题方案解析
- C+虚函数实现多态性的思考
- Zzreal的大数据笔记-SparkDay04
- 180数字集团品牌升级 启用域名180.ai
- iDC预测全球物联网花费在2018年至7720亿美金
- 北京青年报:用数据说话应是网络强国标配
- 3字母域名谁不爱?游戏门户启用价值六位数的域名
- 中国版Space X首台“民营火箭”发动机试车成功;贾跃亭甘薇在美欢度圣诞,证监局喊破嗓子他也不回家;谷歌AI新技能
- 我的写作工具链
- 微信小程序更新新能力:四大功能让小程序更火爆!一起来了解更新吧,快来学习吧
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 解决VScode配置远程调试Linux程序的问题
- Android EasyBarrage实现轻量级弹幕效果
- android 获取本机其他app的版本信息的示例代码
- android相册选择图片的编码实现代码
- ClickHouse和他的朋友们(2)MySQL Protocol和Read调用栈
- Android图片三级缓存的原理及其实现
- Android TextView实现带链接文字事件监听的三种常用方式示例
- Android ViewDragHelper使用介绍
- Android语音声波控件 Android条形波控件
- Ubuntu下安装CUDA10.0以及问题
- Android ListView实现单选及多选等功能示例
- Recyclerview添加头布局和尾布局、item点击事件详解
- Android 中LayoutInflater.inflate()方法的介绍
- Android ListView实现简单列表功能
- Ubuntu16.04上安装CUDA9.0 详细教程