diff --git "a/docs/foundmental/1.MySQL\345\215\217\350\256\256\345\210\206\346\236\220\344\270\216\346\212\223\345\214\205\346\246\202\350\277\260.md" "b/docs/foundmental/1.MySQL\345\215\217\350\256\256\345\210\206\346\236\220\344\270\216\346\212\223\345\214\205\346\246\202\350\277\260.md" index 75a0862a4..67ad4513e 100644 --- "a/docs/foundmental/1.MySQL\345\215\217\350\256\256\345\210\206\346\236\220\344\270\216\346\212\223\345\214\205\346\246\202\350\277\260.md" +++ "b/docs/foundmental/1.MySQL\345\215\217\350\256\256\345\210\206\346\236\220\344\270\216\346\212\223\345\214\205\346\246\202\350\277\260.md" @@ -81,6 +81,7 @@ MySQL 连接的方式有多种, 比如 TCP/IPv4、TCP/IPv6、UNIX domain sockets - TCP三次握手,这里简化不做过多赘述,任何基于TCP的应用都要经历这个过程 - MySQL协议:服务器 -> 客户端:握手初始化消息(Initial HandShake Packet) - 初次握手从服务器发送`Protocol::Handshake`数据包开始。在这之后,客户端可以选择使用`Protocol::SSLRequest`数据包请求建立SSL连接,然后客户端发送`Protocol::HandshakeResponse`数据包。 + - 这里我们忽略SSL过程(假定客户端不请求SSL连接),因为数据库建立SSL连接开销挺大的,实际生产中也很少这样做。 - MySQL协议:客户端 -> 服务器:登陆认证消息(Login Packet) - MySQL协议:服务器 -> 客户端:认证结果消息 () @@ -155,13 +156,17 @@ MySQL 的客户端和服务端交互是以数据包(Packet) 为单位进行的, ![image-20241030174852542](MySQL协议分析与抓包.assets/image-20241030174852542.png) - TCP 三次握手 -- Server——>Client,Server Greeting,Sever 告诉客户端自己的版本、分配的连接 ID、服务器的能力(Capabilities)、认证插件,字符集,Salt 等信息。可以理解为 MySQL 的握手是由 Server 端发起的。 +- - Client——>Server,Login Request,Client 发起的登录请求报文, #### TCP 三次握手 #### 挑战数据包 +Server——>Client ,紧跟TCP连接建立,MySQL 协议的握手是由 Server 端发起的。官网文档叫 [**Protocol::Handshake**](https://dev.mysql.com/doc/dev/mysql-server/8.4.2/page_protocol_connection_phase_packets_protocol_handshake.html) ,在 Wireshark中抓到报文叫 Server Greeting。 + +Sever 告诉客户端自己的版本、分配的连接 ID、服务器的能力(Capabilities)、认证插件,字符集,Salt 等信息。 + MySQL 采用的是挑战-响应方式来进行身份认证。由服务端生成加密用的盐给客户端,提高安全性。 | 名称 | 类型 | 长度 | 含义 | @@ -180,6 +185,8 @@ MySQL 采用的是挑战-响应方式来进行身份认证。由服务端生成 #### 认证数据包 + + #### 切换加密算法 如果挑战数据包返回的`Authentication Plugin`认证插件与你的用户密码加密方式不一致(比如你的用户采用的是`mysql_native_password`加密,而服务器返回的是`caching_sha2_password`),那么校验肯定失败,所以需要更换加密方式。服务器会发送一个切换认证插件请求数据包来指示客户端重新加密密码并发送。