为什么 mysqli_connect() 必须接收未加密的密码参数?

Why mysqli_connect() must receive the password parameter with no encryption?

我创建了一个用户来使用我的数据库

CREATE USER 'my_user'@'localhost' IDENTIFIED BY 'my_pass';
GRANT ALL PRIVILEGES ON * . * TO 'my_user'@'localhost';
FLUSH PRIVILEGES;

通行证以加密模式存储在 mysql.user table.

但是当我使用 mysqli_connect() 方法时,我发现当我将传递作为参数时,如果我不这样做,我必须提供我在查询中使用的未加密的原始值不想得到著名的 "Connect failed: Access denied for user 'my_user'@'localhost' (using password: YES)".

但这实际上是与数据库中存储的字符串值(加密版本)不同的字符串值。

怎么样?如果有人访问我建立连接的 .PHP 文件,将加密版本作为参数提供不是更安全吗?为什么 mysqli_connection 不接受它?有办法吗?

作为用户,您不知道密码是如何加密的(实际上根本没有加密,而是散列)。

您只需传递密码,MySQL 就可以执行与原始密码相同的散列运算,并将其与存储的内容进行比较。如果您传递散列版本,散列的全部好处就消失了:如果有人从服务器获取散列,他们就可以使用这些来登录,就好像它们是普通密码一样。哈希然后成为密码。

额外的好处是 MySQL,因为它有原始密码,可以用更好的算法重新散列它,加一点盐并存储改进后的版本。如果它永远得不到原件,那是做不到的。 PHP's password functions也支持这个。您可以检查 password_needs_rehash 散列密码是否仍然正确散列,如果不是则更新您的数据库。

因此,为了安全起见,您将需要采取其他措施。这些至少是:

  • 将密码存储在位于文档根目录之外的包含文件中。这样,没有人可以直接打开该文件。
  • 您可以防止包含文件在未被包含的情况下被打开(例如通过检查在 index.php 中设置的定义)。这很好,但是如果 PHP 由于配置错误而失败,人们只能浏览文件的源代码,所以坚持之前的规则。
  • 始终创建一个特殊的数据库用户。不要使用 root。授予此用户足够的权限来操作数据库,但不能再多了。例如,无权删除表格。
  • 总是给那个用户一个唯一的密码。您不必记住此密码。只生成带有大量字符的随机垃圾。
  • 定期更改密码。也许您甚至可以编写脚本并将更新后的密码存储在配置中。