php - Mysql密码散列方法旧与新

标签 php mysql mysql-error-1044 password-hash

我正在尝试从位于 slicehost(两个不同的托管公司)的服务器中的 php 脚本连接到 dreamhost 的 mysql 服务器。 我需要这样做,以便我可以将 slicehost 上的新数据传输到 dreamhost。使用转储不是一种选择,因为表结构不同,我只需要传输一小部分数据(100-200 条每日记录) 问题是我在 slicehost 使用新的 MySQL 密码散列方法,而 dreamhost 使用旧方法,所以我得到

$link = mysql_connect($mysqlHost, $mysqlUser, $mysqlPass, FALSE); 

Warning: mysql_connect() [function.mysql-connect]: OK packet 6 bytes shorter than expected
Warning: mysql_connect() [function.mysql-connect]: mysqlnd cannot connect to MySQL 4.1+ using old authentication
Warning: mysql_query() [function.mysql-query]: Access denied for user 'nodari'@'localhost' (using password: NO) 

事实:

  • 我需要在 slicehost 上继续使用新方法,我不能使用旧的 php 版本/库
  • 数据库太大,不能每天转储
  • 即使我这样做了,表也有不同的结构
  • 我每天只需要复制其中的一小部分(仅当天的更改,100-200 条记录)
  • 由于表格差异很大,我需要使用 php 作为桥梁来规范化数据
  • 已经用谷歌搜索过了
  • 已经与两位支持人员交谈过

对我来说更明显的选择是在 dreamhost 开始使用新的 MySQL 密码散列方法,但他们不会改变它,而且我不是 root,所以我自己不能这样做。

有什么天马行空的想法吗?

根据 VolkerK 的建议:

mysql> SET SESSION old_passwords=0;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc'));
+------------------------+-------------------------+-------------------------+
| @@global.old_passwords | @@session.old_passwords | Length(PASSWORD('abc')) |
+------------------------+-------------------------+-------------------------+
|                      1 |                       0 |                      41 |
+------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)

现在显而易见的事情是运行一个 mysql> SET GLOBAL old_passwords=0; 但我需要 super 特权才能做到这一点,他们不会给我

如果我运行查询

SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');

我得到了错误

ERROR 1044 (42000): Access denied for user 'nodari'@'67.205.0.0/255.255.192.0' to database 'mysql'

我不是 root...

dreamhost 支持人员坚持说问题出在我这边。但他说他会运行我告诉他的任何查询,因为它是一个私有(private)服务器。 所以,我需要准确地告诉这个人该跑什么。 所以,叫他跑

SET SESSION old_passwords=0;
SET GLOBAL old_passwords=0;
SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');
grant all privileges on *.* to nodari@HOSTNAME identified by 'new password';

会是一个好的开始吗?

最佳答案

在某些情况下,您仍然可以设置和使用“新的哈希算法密码”。
MySQL 4.1+ 服务器能够处理这两种登录算法。使用哪一个与旧密码变量无关。如果 MySQL 找到以 * 开头的 41 个字符长的散列,它会使用新系统。并且 PASSWORD() 函数也可以使用这两种算法。如果字段 mysql.user.Password 足够宽以存储 41 个字符并且旧密码变量为 0,它将创建一个"new"密码。 documention for old_passwords 表示 Variable Scope Both 因此您可以为您的 session 更改它。
连接到 MySQL 服务器(尽管全局 old_passwords = 1,但客户端能够这样做),例如HeidiSQL 并尝试以下操作:

SET SESSION old_passwords=0;
SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc'));

如果它打印 1, 0, 41 (意味着全局旧密码打开,但对于 session 它关闭并且 PASSWORD() 返回一个"new"密码)你应该能够使用 set a new password在同一 session 中为您的帐户使用新算法。

但是如果 dreamhost 真的想禁用新的密码算法,mysql.user.Password 字段的长度将少于 41 个字符,对此无能为力(除了唠叨他们)。

关于php - Mysql密码散列方法旧与新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1892607/

相关文章:

mysql - 使用喜欢/不喜欢和每天平均观看次数的排名算法

mysql - 避免 MySQL1044 错误

mysql - 连接到外部 mysql 数据库时出现问题

php - 如何处理图像的 MIME 类型 "application/octet-stream"?

php - "Did you mean"php 和 mysql 的功能

php - 在 WooCommerce 中的产品页面上的产品简短描述上方添加内容

php - 将项目上传到站点后,无法解决 Fiverr 脚本中的错误成员函数 getrows()

php - 获取一个值介于两个列值之间的数据库结果

php - 直接在 php 主页面中包含 javascript 文件与在 php 主页面中包含 php 子页面之间的区别?