hash_stage1 = sha1(password) hash_stage2 = sha1(hash_stage1) reply = sha1(scramble, hash_stage2) ^ hash_stage1复制代码
// mysql.user表中, 对应user的passwd实际上是hash_stage2 res1 = sha1(scramble, hash_stage2) hash_stage1 = reply ^ res1 hash_stage2_reassured = sha1(hash_stage1) 再根据hash_stage2_reassured == hash_stage2(from mysql.user)是否一致来判定是否合法复制代码
#0 parse_client_handshake_packet #1 server_mpvio_read_packet #2 native_password_authenticate #3 do_auth_once #4 acl_authenticate #5 check_connection #6 login_connection #7 thd_prepare_connection #8 do_handle_one_connection 复制代码
if (plugin) { st_mysql_auth *auth= (st_mysql_auth *) plugin_decl(plugin)->info; res= auth->authenticate_user(mpvio, &mpvio->auth_info); ...复制代码
/* generate the scramble, or reuse the old one */ if (mpvio->scramble[SCRAMBLE_LENGTH]) create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand); /* send it to the client */ if (mpvio->write_packet(mpvio, (uchar*) mpvio->scramble, SCRAMBLE_LENGTH + 1)) DBUG_RETURN(CR_AUTH_HANDSHAKE); /* read the reply with the encrypted password */ if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0) DBUG_RETURN(CR_AUTH_HANDSHAKE); DBUG_PRINT("info", ("reply read : pkt_len=%d", pkt_len));复制代码
if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION) { /* Get the password field. */ passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet, &passwd_len); } else { /* Old passwords are zero terminatedtrings. */ passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len); } ...复制代码
// server decode回包中的加密信息 // 把上面提到的三个公式包在函数中 my_boolcheck_scramble_sha1(const uchar *scramble_arg, const char *message, const uint8 *hash_stage2) { uint8 buf[SHA1_HASH_SIZE]; uint8 hash_stage2_reassured[SHA1_HASH_SIZE]; /* create key to encrypt scramble */ compute_sha1_hash_multi(buf, message, SCRAMBLE_LENGTH, (const char *) hash_stage2, SHA1_HASH_SIZE); /* encrypt scramble */ my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH); /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ compute_sha1_hash(hash_stage2_reassured, (const char *) buf, SHA1_HASH_SIZE); return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));}复制代码