You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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.

原代码的错误点

  1. 盐的处理错误:将二进制盐转成了十六进制字符串,而MySQL要求盐是base64编码的原始二进制数据
  2. PBKDF2参数错误:输出长度指定为salt.length,实际应为SHA256的固定长度32字节
  3. 哈希字符串格式错误:盐部分直接使用十六进制字符串,而非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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:15:59