本文想要說明的是,當我們用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
