10
博客[oceanbase] ob_native_password 加密原理

[oceanbase] ob-c7电子娱乐

2024-12-30用户实践

导读

换换口味, 来瞧瞧国产数据库oceanbase的密码相关知识. 由于我们可以使用mysql命令连接ob, 所以基本上可以确定ob的密码加密和mysql的mysql_native_password一样了.(认证过程和加密方式都一样, 所以这口味换了个寂寞…).

国产数据库很多安装都费劲, 而且不少要求的资源根本不是笔记本能满足的, 想要学习的dba/开发很难入手. 但最近白嫖了1年的ob,就体验体验

以前二手的t450都能安装12c rac, 但在国产数据库面前就甭想了, 我20c 64gb的笔记本都只能勉强安装丐版.

1735528772

原理

我们还是先使用mysql登录数据库查看下库信息, 比mysql少了sys和performance_schema, 有的mysql和information_schema估计也是虚拟的, 真实的数据应该是在oceanbase下面.

mysql> show databases;
 -------------------- 
| database           |
 -------------------- 
| db1                |
| information_schema |
| mysql              |
| oceanbase          |
 -------------------- 
4 rows in set (0.04 sec)

我们本次主要看mysql.user表

mysql> select * from mysql.user where user='ddcw'\g
*************************** 1. row ***************************
                     host: %
                     user: ddcw
                 password: *6bb4837eb74329105ee4568dda7dc67ed2ca2ad9
              select_priv: n
              insert_priv: n
              update_priv: n
              delete_priv: n
              create_priv: n
                drop_priv: n
              reload_priv: n
            shutdown_priv: n
             process_priv: n
                file_priv: n
               grant_priv: n
          references_priv: n
               index_priv: n
               alter_priv: n
             show_db_priv: n
               super_priv: n
    create_tmp_table_priv: n
         lock_tables_priv: n
             execute_priv: n
          repl_slave_priv: n
         repl_client_priv: n
         create_view_priv: n
           show_view_priv: n
      create_routine_priv: n
       alter_routine_priv: n
         create_user_priv: n
               event_priv: n
             trigger_priv: n
   create_tablespace_priv: n
                 ssl_type: 
               ssl_cipher: 
              x509_issuer: 
             x509_subject: 
            max_questions: 0
              max_updates: 0
          max_connections: 0
     max_user_connections: 0
                   plugin: ob_native_password
    authentication_string: 
         password_expired: 
           account_locked: n
  drop_database_link_priv: n
create_database_link_priv: n
         create_role_priv: n
           drop_role_priv: n
1 row in set (0.09 sec)

密码插件叫ob_native_password, 很容易让人联想到mysql_native_password. 加密之后的密码是*6bb4837eb74329105ee4568dda7dc67ed2ca2ad9, 居然是小写字母… 而且不是mysql的名字authentication_string, 感觉兼容性比较怪. (兼容了,但不完全兼容)

原理

加密原理应该和mysql一样, 也是对密码做2次hash1. 我们查看源码(oceanbase-develop/deps/oblib/src/lib/encrypt/ob_encrypted_helper.cpp)发现了如下注释信息:

/*
 * mysql validation logic:
 *  server stores the 'stage2' hash, which is cleartext password calc-ed sha1 twice.
 *  when login, server sends random scramble str.
 *  client gets the scramble, use this logic to generate login rsp:
 *    stage1 = sha1(passwd)
 *    stage2 = sha1(stage1)
 *    scrambled_stage2 = sha1(scramble_got_from_server, stage2)
 *    login_rsp = xor(stage1, scrambled_stage2)
 *
 **/
int obencryptedhelper::encrypt_password(const obstring &raw_pwd, const obstring &scramble_str,
                                        char *pwd_buf, const int64_t buf_len, int64_t ©_len)
{
.....
}
复制

确实是做的2次hash1, (连接的时候会加salt). obo也可以使用mysql连接, 所以obo里面的密码应该也是这样的.但没得相关环境,无法验证(白嫖的1年只能选一种模式…)

验证

我们可以自己使用sql来验证下.

mysql> select password from mysql.user where user='ddcw';
 ------------------------------------------- 
| password                                  |
 ------------------------------------------- 
| *6bb4837eb74329105ee4568dda7dc67ed2ca2ad9 |
 ------------------------------------------- 
1 row in set (0.06 sec)
mysql> select concat('*', sha1(unhex(sha1('123456'))));
 ------------------------------------------- 
| concat('*', sha1(unhex(sha1('123456'))))  |
 ------------------------------------------- 
| *6bb4837eb74329105ee4568dda7dc67ed2ca2ad9 |
 ------------------------------------------- 
1 row in set (0.13 sec)
这密码字段叫password, 于是mysql客户端就不会记录到历史命令中, 就无法往上翻了…

密码确实是做的两次sha1.

我们再来看看我们之前写的, 这个脚本是兼容某些兼容mysql的国产数据库的. 测试还是非常方便.

import pymysql
conn = pymysql.connect(
	host='xxxxxxx.oceanbase.cloud',
	port=3306,
	user='ddcw',
	password='123456',
	)
cursor = conn.cursor()
cursor.execute('select @@version')
print(cursor.fetchall())

很遗憾, 我们的脚本并不行…
1735528797

来看看正版的pymysql 是没得问题的. 这兼容性就比较怪了…(有空了再去调试调试吧.)
1735528806

总结

ob_native_password和mysql的mysql_native_password基本上是一样的(从原理来说). 比较要兼容性嘛.具体实现不同. 而且登录时密码验证过程有点区别(我那个丐版pymysql就是例子.)


点赞10
收藏

声明

本网站下的“博客”等板块为技术爱好者提供分享、交流的平台。发布者发布的任何内容、信息等,并不反映或代表本网站的观点、立场或政策。本网站不对其任何内容和信息的错误以及由此产生的损失或损坏承担任何责任。

尊重知识产权是本网站的基本原则之一,如您在使用本网站过程中发现本网站中存在侵犯您或其他第三人合法知识产权的情况,请您即可将侵权材料及初步证据提交至下述邮箱:obcompliance@oceanbase.com 。本网站将在收到材料后尽快进行审核及处理。

已发布 1 篇博文

网站地图