首頁  >  文章  >  資料庫  >  mysql 協定的認證包及程式碼詳情介紹

mysql 協定的認證包及程式碼詳情介紹

黄舟
黄舟原創
2017-03-08 14:06:241246瀏覽


git


https://github.com/sea-boat/mysql-protocol

概況

mysql客戶端登陸到mysql服務端需要一個互動的過程,首先服務端給客戶端發送的初始握手包,客戶端接收到握手包後向服務端返回認證包。如下,這裡分析下認證包。

client                 server
   |-------connect------>|
   |                     |
   |<-----handshake------|
   |                     |
   |---authentication--->|
   |                     |

mysql通訊訊息結構

mysql 協定的認證包及程式碼詳情介紹

#Payload


###########################################################################################################################。 ##認證套件###
4              capability flags, CLIENT_PROTOCOL_41 always set
4              max-packet size
1              character set
string[23]     reserved (all [0])
string[NUL]    username
  if capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA {
lenenc-int     length of auth-response
string[n]      auth-response
  } else if capabilities & CLIENT_SECURE_CONNECTION {
1              length of auth-response
string[n]      auth-response
  } else {
string[NUL]    auth-response
  }
  if capabilities & CLIENT_CONNECT_WITH_DB {
string[NUL]    database
  }
  if capabilities & CLIENT_PLUGIN_AUTH {
string[NUL]    auth plugin name
  }
  if capabilities & CLIENT_CONNECT_ATTRS {
lenenc-int     length of all key-values
lenenc-str     key
lenenc-str     value
   if-more data in &#39;length of all key-values&#39;, more keys and value pairs
  }
###更多詳情: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse###### #認證套件操作######1.認證套件類別###
/**
 * 
 * @author seaboat
 * @date 2016-09-25
 * @version 1.0
 * <pre class="brush:php;toolbar:false"><b>email: </b>849586227@qq.com
 * 
blog: http://www.php.cn/;/pre>
 * 

mysql auth packet.

 */public class AuthPacket extends MySQLPacket {     private static final byte[] FILLER = new byte[23];         public long clientFlags;         public long maxPacketSize;         public int charsetIndex;         public byte[] extra;         public String user;         public byte[] password;         public String database;         public void read(byte[] data) {         MySQLMessage mm = new MySQLMessage(data);         packetLength = mm.readUB3();         packetId = mm.read();         clientFlags = mm.readUB4();         maxPacketSize = mm.readUB4();         charsetIndex = (mm.read() & 0xff);                 int current = mm.position();                 int len = (int) mm.readLength();                 if (len > 0 && len #########加上解密工具#########
/**
 * 
 * @author seaboat
 * @date 2016-09-25
 * @version 1.0
 * <pre class="brush:php;toolbar:false"><b>email: </b>849586227@qq.com
 * 
blog: http://www.php.cn/;/pre>
 * 

a security util .

 */public class SecurityUtil {     public static final byte[] scramble411(byte[] pass, byte[] seed)                 throws NoSuchAlgorithmException {         MessageDigest md = MessageDigest.getInstance("SHA-1");                 byte[] pass1 = md.digest(pass);         md.reset();                 byte[] pass2 = md.digest(pass1);         md.reset();         md.update(seed);                 byte[] pass3 = md.digest(pass2);                 for (int i = 0; i #####################################################################################################測試類別#########
/**
 * 
 * @author seaboat
 * @date 2016-09-25
 * @version 1.0
 * <pre class="brush:php;toolbar:false"><b>email: </b>849586227@qq.com
 * 
<b>blog: </b>http://www.php.cn/;/pre>
 * <p>test auth packet.</p>
 */public class AuthPacketTest {
    @Test
    public void produce() {        
    // handshake packet's rand1 and rand2
        byte[] rand1 = RandomUtil.randomBytes(8);        
        byte[] rand2 = RandomUtil.randomBytes(12);        
        byte[] seed = new byte[rand1.length + rand2.length];
        System.arraycopy(rand1, 0, seed, 0, rand1.length);
        System.arraycopy(rand2, 0, seed, rand1.length, rand2.length);

        AuthPacket auth = new AuthPacket();
        auth.packetId = 0;
        auth.clientFlags = getClientCapabilities();
        auth.maxPacketSize = 1024 * 1024 * 16;
        auth.user = "seaboat";        try {
            auth.password = SecurityUtil
                    .scramble411("seaboat".getBytes(), seed);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        auth.database = "test";

        ByteBuffer buffer = ByteBuffer.allocate(256);
        auth.write(buffer);
        buffer.flip();        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes, 0, bytes.length);
        String result = HexUtil.Bytes2HexString(bytes);
        System.out.println(result);
        assertTrue(Integer.valueOf(result.substring(0, 2), 16) == result
                .length() / 2 - 4);

        AuthPacket auth2 = new AuthPacket();
        auth2.read(bytes);
        assertTrue(auth2.database.equals("test"));
    }    protected int getClientCapabilities() {        
    int flag = 0;
        flag |= Capabilities.CLIENT_LONG_PASSWORD;
        flag |= Capabilities.CLIENT_FOUND_ROWS;
        flag |= Capabilities.CLIENT_LONG_FLAG;
        flag |= Capabilities.CLIENT_CONNECT_WITH_DB;
        flag |= Capabilities.CLIENT_ODBC;
        flag |= Capabilities.CLIENT_IGNORE_SPACE;
        flag |= Capabilities.CLIENT_PROTOCOL_41;
        flag |= Capabilities.CLIENT_INTERACTIVE;
        flag |= Capabilities.CLIENT_IGNORE_SIGPIPE;
        flag |= Capabilities.CLIENT_TRANSACTIONS;
        flag |= Capabilities.CLIENT_SECURE_CONNECTION;        
        return flag;
    }
}
##########

以上是mysql 協定的認證包及程式碼詳情介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn