如何在Ruby中生成MySQL caching_sha2_password格式带盐哈希密码
如何用Ruby生成MySQL 8.0的caching_sha2_password格式哈希密码
问题背景
之前在MySQL 5.7中,可通过以下Ruby代码生成mysql_native_password格式哈希:
def generate_mysql_password(plaintext_password) digest = OpenSSL::Digest.new('sha1', OpenSSL::Digest.new('sha1', plaintext_password).digest) return "*" + digest.hexdigest.upcase end
生成的哈希可直接用于CREATE USER语句。但升级到MySQL 8.0后,默认认证插件变为caching_sha2_password,自行编写的生成代码始终报错ERROR 1827 (HY000): The password hash doesn't have the expected format.
原代码的错误点
- 盐的处理错误:将二进制盐转成了十六进制字符串,而MySQL要求盐是base64编码的原始二进制数据
- PBKDF2参数错误:输出长度指定为
salt.length,实际应为SHA256的固定长度32字节 - 哈希字符串格式错误:盐部分直接使用十六进制字符串,而非base64编码后的结果
正确的Ruby实现代码
require 'openssl' require 'base64' def generate_caching_sha2_password(plaintext_password) # caching_sha2_password固定使用12字节盐、5000次迭代 salt = OpenSSL::Random.random_bytes(12) digest = OpenSSL::Digest.new('sha256') # 执行PBKDF2-HMAC-SHA256计算,输出32字节哈希 hashed_password = OpenSSL::PKCS5.pbkdf2_hmac(plaintext_password, salt, 5000, 32, digest) # 按MySQL要求的格式拼接:$A$005$<base64盐>$<base64哈希> salt_base64 = Base64.strict_encode64(salt) hash_base64 = Base64.strict_encode64(hashed_password) "$A$005$#{salt_base64}$#{hash_base64}" end # 使用示例 password = "my_strong_password" valid_hash = generate_caching_sha2_password(password) puts valid_hash
使用说明
生成的哈希字符串可直接用于创建用户:
CREATE USER IF NOT EXISTS 'test1'@'%' IDENTIFIED WITH caching_sha2_password AS '#{valid_hash}';
关键细节
- 盐必须是12字节的原始二进制数据,禁止转十六进制
- 迭代次数固定为5000,对应格式中的
005标识 - 必须使用
Base64.strict_encode64生成无换行的base64编码结果,否则MySQL会判定格式错误
内容的提问来源于stack exchange,提问作者binhdt2611
相关产品推荐
相关产品推荐

