GA

2026/10/20

caching_sha2_passwordのauthentication_stringを計算してもらう

TL;DR


mysql84 149071> CREATE USER yoku0825 IDENTIFIED WITH caching_sha2_password BY 'test';
Query OK, 0 rows affected (0.00 sec)

mysql84 149071> CREATE USER yoku0826 IDENTIFIED WITH caching_sha2_password BY 'test';
Query OK, 0 rows affected (0.01 sec)

mysql84 149071> SELECT user, host, authentication_string FROM mysql.user WHERE user LIKE 'yoku%';  -- 制御文字が入ることがあって表示が変になることあるある
+----------+------+------------------------------------------------------------------------+
| user     | host | authentication_string                                                  |
+----------+------+------------------------------------------------------------------------+
| yoku0825 | %    | $A$005$2thQcC;,Av1@ IY~BihHGrWskcdpi.zGu1kMoFuqtQJ9eMjyRCkaRos93557 |
| yoku0826 | %    | $A$005Hv%b6
.&N%-JBo^3uqAgcrXEygcbJVXEdUorl/y4RVg0JEte08LGQmVJi2 |
+----------+------+------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql84 149071> SELECT user, host, HEX(authentication_string) FROM mysql.user WHERE user LIKE 'yoku%';  -- HEXで取ると安全
+----------+------+----------------------------------------------------------------------------------------------------------------------------------------------+
| user     | host | HEX(authentication_string)                                                                                                                   |
+----------+------+----------------------------------------------------------------------------------------------------------------------------------------------+
| yoku0825 | %    | 24412430303524327468105163433B2C41763140010949591C7E42696848477257736B636470692E7A4775316B4D6F46757174514A39654D6A7952436B61526F733933353537 |
| yoku0826 | %    | 24412430303524084876031A256201360C2E264E252D4A426F155E337571416763725845796763624A56584564556F726C2F7934525667304A45746530384C47516D564A6932 |
+----------+------+----------------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

生の authentication_string の $ はデリミタで、 $A$005$ が SHA256ダイジェストで5000回ストレッチ を表すらしい ( ITERATION_MULTIPLIER は9.7.2現在 1000で固定 )。
その後、 SALT_LENGTH = 20 バイトのソルトと STORED_SHA256_DIGEST_LENGTH = 43 バイトのダイジェストがデリミタなしでくっつく。

認証としては「同じソルトで同じ回数ストレッチしたら同じダイジェストにたどり着く」だけで十分なので、「一度作ったアカウントのauthentication_stringはパスワードが同じなら使い回せる」のは mysql_native_password の時と同じ。

mysql84 149226> CREATE USER yoku0827 IDENTIFIED WITH caching_sha2_password AS x'24412430303524084876031A256201360C2E264E252D4A426F155E337571416763725845796763624A56584564556F726C2F7934525667304A45746530384C47516D564A6932'; -- yoku0826のauthentication_stringをHEXにしたもの。 x'..' は UNHEX('..') と同じだけどUNHEX関数を噛ませると構文的にエラーになるので x'..' (これはリテラル扱い) で食わせる
Query OK, 0 rows affected (0.01 sec)

$ mysql84 -uyoku0827 -ptest -e "SHOW GRANTS"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------------------------+
| Grants for yoku0827@%                |
+--------------------------------------+
| GRANT USAGE ON *.* TO `yoku0827`@`%` |
+--------------------------------------+

なのでソルトを自分で指定すればこの43バイトダイジェストの部分作れるのでは? と思ってはいたものの、 Caching_sha2_password::generate_crypt5 からの my_crypt_genhash を見てもopensslをちゃんと使わずに手元で計算するの無理だと思っていたが、世はAI時代でPythonの形で出してもらった。便利な世の中になったものだ…。

Kimi-K2.7-Codeに書いてもらったソルト固定でcaching_sha2_passwordの値を計算してもらうスクリプト


余談。

たまに驚かれるけれど、 mysql_native_password のハッシュは一般的なLinuxのコマンドだけでも作れたりする。

$ echo -n "mypass" | sha1sum | awk '{print $1}' | xxd -r -p | sha1sum | awk '{print toupper("*"$1)}'
*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4
  
$ mysql -h 172.17.0.6 -e "SELECT PASSWORD('mypass')"
+-------------------------------------------+
| PASSWORD('mypass')                        |
+-------------------------------------------+
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
+-------------------------------------------+