mysql 密码算法

Posted by hcy on May 11, 2022

mysql 密码算法

mysql 5.x版本后,密码算法有变更,在此记录下来。

首先看mysql连接时,服务端发送的握手报文,这里主要是保存两个salt

image-20220511150444355

然后再看客户端返回的数据包,重要的部分就是用户名密码部分。

image-20220511150621224

下面看如何根据上面的信息构建密码。

其中pass为真实密码,salt为两个salt相加。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    private static byte[] scramble(byte[] pass, byte[] salt) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1"); //sha1(password)
            byte[] passwdShar1 = md.digest(pass);
            md.reset();

            byte[] d2 = md.digest(passwdShar1); // sha1(sha1(password))
            md.reset();
            byte[] d3 = new byte[salt.length + d2.length]; //salt + sha1(sha1(password))
            System.arraycopy(salt, 0, d3, 0, salt.length);
            System.arraycopy(d2, 0, d3, salt.length, d2.length);
            byte[] d4 = md.digest(d3); //sha1(salt <concat> sha1(sha1(password)))
            for (int i = 0; i < passwdShar1.length; i++) {   // XOR
                passwdShar1[i] = (byte) (passwdShar1[i] ^ d4[i]);
            }
            return passwdShar1;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

伪代码为:

SHA1( password ) XOR SHA1(“20-bytes random data from server” SHA1( SHA1( password ) ) )

当然该算法在5.7版本试验成功,其他旧版本或新版本均没试过,已抓包结果为准。

参考链接

https://stackoverflow.com/questions/48477121/wireshark-password-capture-of-mysql-traffic


转载请注明出处:https://www.huangchaoyu.com/2022/05/11/mysql-密码算法/