mysql的client和sever之间通信password的传输方式

本文想要说明的是,当我们用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

 

posted on 2016-06-01 16:27  蒋乐兴的技术随笔  阅读(2332)  评论(0编辑  收藏  举报

导航