暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[oceanbase] ob_native_password 加密原理

原创 大大刺猬 2024-12-30
86

导读

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

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

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

image.png

原理

我们还是先使用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 &copy_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的脚本, 这个脚本是兼容某些兼容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())

很遗憾, 我们的脚本并不行…
image.png

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

总结

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

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

I
暂无图片
获得了465次点赞
暂无图片
内容获得150次评论
暂无图片
获得了1568次收藏
目录
  • 导读
  • 原理
    • 原理
    • 验证
  • 总结