本文想要说明的是,当我们用mysql -uroot -p1234567 -h127.0.0.1 -P3306 去连接mysql server时密码是通过什么样的形式传过去的呢?
首先密码这种东西明文传过去自然是不安全的,那怎么办呢?那自然就要加密啦,本文讲解的就是这个加密方法(python代码描述);以NativePasswordAuthPlugin
为例,明文,sha256_password都比较简单
总的来看密码要经过三次sha(安全hash算法)提取特征值,然后把第一次sha和第三次sha的特征值打包成一个20字节的输出,这个输出就是最终在通信链路上
传递的password
以下是从数据包中看到的信息
python描述
class MySQLNativePasswordAuthPlugin(BaseAuthPlugin): """Class implementing the MySQL Native Password authentication plugin""" requires_ssl = False plugin_name = 'mysql_native_password' def prepare_password(self): """Prepares and returns password as native MySQL 4.1+ password""" #### #如果self._auth_data为空就报错退出 if not self._auth_data: raise errors.InterfaceError("Missing authentication data (seed)") #### #如果没有密码,就返回空字节 if not self._password: return b'' #### #如果执行到了这里说明是有,授权数据(_auth_data),有密码的(_password) password = self._password ### #调用encode 把password从str对象变成bytes对象 if isstr(self._password): password = self._password.encode('utf-8') else: password = self._password ### #把bytes对象转化成buffer,对象3.x已经可以不转了 if PY2: password = buffer(password) # pylint: disable=E0602 try: auth_data = buffer(self._auth_data) # pylint: disable=E0602 except TypeError: raise errors.InterfaceError("Authentication data incorrect") else: password = password auth_data = self._auth_data hash4 = None #### #密码要经过三次sha try: hash1 = sha1(password).digest() hash2 = sha1(hash1).digest() hash3 = sha1(auth_data + hash2).digest() if PY2: xored = [ord(h1) ^ ord(h3) for (h1, h3) in zip(hash1, hash3)] else: xored = [h1 ^ h3 for (h1, h3) in zip(hash1, hash3)] ###打包成20字节大小 hash4 = struct.pack('20B', *xored) except Exception as exc: raise errors.InterfaceError( "Failed scrambling password; {0}".format(exc)) return hash4