Home  >  Article  >  Database  >  A detailed introduction to the authentication package and code of the mysql protocol

A detailed introduction to the authentication package and code of the mysql protocol

黄舟
黄舟Original
2017-03-08 14:06:241257browse


git


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

Overview

Mysql client requires an interactive process to log in to the mysql server. First, the server sends an initial handshake packet to the client. After receiving the handshake packet, the client returns an authentication packet to the server. As follows, the authentication package is analyzed here.

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

mysql communication message structure

A detailed introduction to the authentication package and code of the mysql protocol

##PayloadAuthentication Package
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
  }

More details: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse

Authentication package operation

1. Authentication package class

/**
 * 
 * @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 
  1. Encryption and decryption tool

  2. /**
     * 
     * @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>a security util .</p>
     */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 
  1. Test class

  2. /**
     * 
     * @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;
        }
    }


The above is the detailed content of A detailed introduction to the authentication package and code of the mysql protocol. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn