【问题标题】:How to create password hash for MySQL externally?如何在外部为 MySQL 创建密码哈希?
【发布时间】:2018-11-27 14:28:44
【问题描述】:

我以前可以通过两次 sha1 运行我的密码来创建与 MySQL 兼容的密码,但似乎这在 MySQL 8 中不起作用。

MySQL 现在似乎在使用这些密码插件。因此语法是(在 JS 中):

const createUserSql = `CREATE USER ${db.escapeValue(agency.login)} IDENTIFIED WITH mysql_native_password BY ${db.escapeValue(passwordHash)};`;

我想在 Node.js 中创建适用于 MySQL 的密码。我知道我可以只使用纯文本密码并让 MySQL 对其进行哈希处理,但我正在将此 SQL 打印到终端并且我不希望密码可见,所以我想对它们进行预哈希处理。

什么算法适用于 MySQL 8?我愿意使用任何内置的密码插件。

sha256_password 听起来不错,但我不认为它是一个直接的 sha256 哈希,听起来它内置了盐,所以我不确定如何在 Node.js 中创建一个。


MySQL PASSWORD() 函数也消失了。我真的不想用SELECT PASSWORD(:plainTextPass) 来散列我的密码,但现在这甚至不是一个选择。

【问题讨论】:

    标签: mysql node.js mysql-8.0


    【解决方案1】:

    致在搜索信息时碰巧发现此内容的其他人:

    我们正在将 MySQL 5.0 安装先升级到 5.7,然后再升级到 8.0。我们依赖mysql_native_password 身份验证插件,因为这是 Ansible 目前唯一支持的插件,而且我们所有的旧用户帐户都具有该方案的哈希值。我们希望我们的 Ansible 任务为 mysql_user 模块提供预制哈希,包括在我们到达那里后的 8.0 时代。

    经过一番挖掘,我找到了这篇博文:

    https://blog.pythian.com/hashing-algorithm-in-mysql-password-2/

    PASSWORD() 函数在 MySQL 8 中消失了,但看起来这会返回完全相同的值:

    SELECT CONCAT('*', UPPER(SHA1(UNHEX(SHA1('the_password')))));

    【讨论】:

      【解决方案2】:

      密码哈希不再仅基于明文计算。所以密码()函数是不可能实现的。顺便说一句,从 5.5 开始就是这样:只需查看 old_passwords 系统变量。 从 8.0 开始,我们决定让身份验证插件进行哈希处理,并且我们向身份验证插件 API 添加了新方法。 理论上我可以创建一个新的密码函数,它需要额外的参数(身份验证方法、用户名、明文密码等)并调用相关的插件。

      但无论如何,所有结果都存储在 mysql.user.authentication_string 中。 并且始终可以通过 CREATE USER ... IDENTIFIED WITH ... AS ... 语法传递回 MySQL。

      因此,您需要的解决方法是执行 CREATE USER,然后执行 SHOW CREATE USER(最终 DROP USER)。

      如果您仍然想恢复 PASSWORD 功能的变体,请在 bugs.mysql.com 中提交功能请求。 仅供参考,我们也接受代码贡献:)

      使用的散列本身也不是火箭科学。我相信对于 8.0 的新默认身份验证方法 (caching_sha256),它在此处定义:https://dev.mysql.com/doc/dev/mysql-server/latest/page_caching_sha2_authentication_exchanges.html#sect_caching_sha2_definition

      因此,如果您不想往返于服务器,可以使用上述定义。

      【讨论】:

      • 感谢您对 Joro 的回复!那么我可以做CREATE USER ... IDENTIFIED WITH caching_sha256 AS 'precomputed_hash' 吗? precomputed_hashSHA256(SHA256(user_password)) 在哪里?我读对了吗?还是我需要来自服务器的随机数?
      • 它应该可以工作。作为记录,这就是我们对 CREATE USER 进行 binlog 的方式。我认为你不需要服务器提供任何东西。
      【解决方案3】:

      不确定我是否理解问题所在。 MySQL 将使用其中一个身份验证插件对您提供的任何内容进行哈希处理(它在幕后实现了一些特定的哈希策略)。

      如果您想在应用程序级别执行额外的哈希,这取决于您,但只要应用程序始终考虑额外的哈希轮次,这应该不是问题。

      您可能需要担心的是确保您使用的客户端支持该身份验证插件。

      举个例子,Node.js 的两个最流行的社区驱动mysqldrivers(我相信这是你的环境)都没有支持默认的身份验证插件 - caching_sha2_password - MySQL 使用8.0(更多细节在answer)。

      但是连接mysql_native_password 帐户(这似乎是您的情况)应该不是问题。

      【讨论】:

      • 我正在编写一个导出 SQL 以创建 MySQL 用户的脚本。我不希望这个 SQL 包含纯文本密码。因此,我想在用户密码到达 MySQL 之前对其进行预哈希处理。我的问题是如何散列这些密码,最好不要连接到 MySQL?如果 sha1'ing 密码曾经是一件简单的事情,但在 MySQL 8 中不再适用。
      • 我还是一头雾水。只要您还在 mysql 上使用相同的密码哈希创建相同的用户帐户,您就可以随意对它们进行哈希处理。使用默认的身份验证插件,MySQL 也会对其进行哈希处理,但这应该不是问题。在任何情况下,如果你打算只做客户端散列,你可以在创建 MySQL 用户时使用mysql_clear_password 插件。
      • “使用默认的身份验证插件,MySQL 也会对其进行哈希处理,但这应该不是问题”——not 怎么会有问题呢?因为双重哈希仍然安全?没关系,但我无法从任何地方登录。我只使用这些哈希来创建用户帐户,我们的应用程序和第 3 方应用程序 (phpmyadmin/adminer) 在将密码发送到 MySQL 之前将对密码进行哈希处理。我创建的哈希必须与 MySQL 内部执行的操作完全匹配,才能发挥作用。
      • 好的,混合第三方应用程序是新信息。无论如何,我看不到带有PASSWORD() 的旧设置在这些条件下如何工作。您仍然必须确保所有第 3 方应用程序都将使用与 PASSWORD() 相同的哈希策略才能使一切正常运行。但也许我错过了一些东西。无论如何,我看不出如何使用 MySQL 8.0。
      • 你错过了一些东西。您只需创建一次 MySQL 用户帐户,然后一切正常。没有一个应用程序必须选择“散列策略”——当你连接时,MySQL 会为你做这件事。
      猜你喜欢
      • 1970-01-01
      • 2014-06-09
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多