哈希与安全

MySQL 密码哈希生成器

为旧版 MySQL 服务器生成 MySQL 4.1+ 的 PASSWORD() 哈希。

给这个工具评分

如何使用 MySQL 密码哈希生成器

  1. 在输入框中键入或粘贴密码。
  2. 41 位字符的哈希会随输入实时显示,以星号开头。
  3. 直接将它复制到您旧版的 mysql.user 表行中。

关于 MySQL 密码哈希生成器

这是 MySQL 的 PASSWORD() 函数,其工作方式自 MySQL 4.1 版本起一直未变。该算法是对原始字节执行两次 SHA-1——即 SHA1(SHA1(password))——结果以大写十六进制形式书写,前面加一个星号,总共构成 41 个字符。星号并不属于摘要本身;它只是一个标记,告诉 MySQL 这是 4.1 时代的格式,而不是此前那种较短的 16 字符哈希。如果你想单独看看这个底层原语,我们的 SHA-1 生成器可以执行单次哈希。

请注意其中缺失的东西:没有盐值。使用相同密码的两个账户会得到相同的 41 字符字符串,而 SHA-1 速度很快,所以这种格式对拥有你 mysql.user 表的攻击者几乎没有多少抵抗力。MySQL 官方也清楚这一点——PASSWORD() 在 MySQL 5.7 中被弃用,并在 MySQL 8.0 中被完全移除,后者默认改用 caching_sha2_password 作为身份验证插件。

所以合理的使用场景是遗留系统:你正在维护一台旧服务器,或者需要直接设置一行 mysql.user 记录而不是通过 SET PASSWORD,又或者正在把账户从仍在存储这类哈希的系统中迁移出来。这些都没问题。但你不应该把这种格式借用到自己应用程序的密码上——它不加盐、速度快,而且已被其官方厂商弃用。请改用 bcrypt

常见问题

为什么哈希以星号开头?

星号标记了 MySQL 4.1+ 格式,用于将其与更早的 16 字符前 4.1 版本哈希区分开来。它是一个前缀,不属于摘要本身——哈希本身是星号之后的 40 个十六进制字符,加起来共 41 个。

MySQL 8 中还有 PASSWORD() 函数吗?

没有了。它在 MySQL 5.7 中被弃用,并在 MySQL 8.0 中被移除,后者默认使用 caching_sha2_password。本工具适用于旧版服务器和迁移场景。

为什么不加盐又速度快在这里是个问题?

由于没有盐值,相同密码在所有账户中都会产生相同的哈希,因此一张预先计算好的查找表就能一次性攻击整张表,重复项也一眼可见。SHA-1 速度也非常快,所以被窃取的 mysql.user 表可以被以极高速率攻击。双重哈希对此并没有起到实质的减缓作用。

我能把这个用于我应用程序的用户密码吗?

请不要这样做。它不加盐、速度快,而且已从现代 MySQL 中移除。请改在普通字段中存储 bcrypt 或 Argon2 哈希。

我的密码会被存储吗?

不会。它会被发送到我们的服务器进行哈希计算,因为浏览器无法以这种确切的双重哈希形式计算 SHA-1,计算完成后会立即丢弃——绝不记录,绝不存储。