MysqlSha1

在4.0版本之前,Mysql使用Mysql323作为Hash存储的方式

在4.1版本之后,Mysql使用MysqlSha1作为Hash存储的方式

Generator

MysqlSha1是基于Sha1的Hash算法,Hash前的星号用于标识以区别于Mysql323

1
2
3
4
5
6
def password(passwd):
import hashlib
_hash = hashlib.sha1(passwd.encode()).digest()
__hash = "*" + hashlib.sha1(_hash).hexdigest().upper()
return __hash
print(password("password"))

值得一提的是第一次Hash结果为二进制

Token

mysql_native_password认证方式下的token生成

1
2
3
4
5
6
7
8
def token(passwd, scramble):
import hashlib
hash1 = hashlib.sha1(passwd.encode()).digest()
hash2 = hashlib.sha1(passwd.encode()).hexdigest()
hash3 = hashlib.sha1(scramble.encode() + hashlib.sha1(hash1).digest()).hexdigest()
token = hex(int(hash2, 16) ^ int(hash3, 16))[2:]
return token
print(token("password", "{?hmkQ3Lb*Ipz3.**1WC"))

Check

mysql_native_password认证方式下的check方法

1
2
3
4
5
6
7
8
9
10
def check(token, __hash, scramble):
import binascii
import hashlib
_hash1 = hashlib.sha1(binascii.unhexlify(hex(int(token, 16) ^ int(hashlib.sha1(scramble.encode() + binascii.unhexlify(__hash[1:].lower().encode())).hexdigest(), 16))[2:].encode())).hexdigest()
_hash2 = __hash[1:].lower()
if _hash1 == _hash2:
return True
else:
return False
print(check("7230ae6e07d2b83f36aca145169248fbcd80b7a4", "*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19", "{?hmkQ3Lb*Ipz3.**1WC"))

在显示的时候Hash都为Hex形式,计算的时候都为Bin形式,在处理的时候需要注意

在网上查阅资料的时候基本没有见过有文章提到Hash计算的时候为二进制,直接治好了我的低血压