MYSQL老密码与php版本扩展关系

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: mysql的用户密码保存在数据库中是加密的。不可逆的。当需要创建一个新的帐号,如果是使用insert插入一条记录,mysql提供了一个函数PASSWORD(),对明文进行加密。所以有如下sql:insert into mysql.user values('帐号名',PASSWORD('设置的帐号密码'));但是,mysql4.1版本之前有些不同。

mysql的用户密码保存在数据库中是加密的。不可逆的。当需要创建一个新的帐号,如果是使用insert插入一条记录,
mysql提供了一个函数PASSWORD(),对明文进行加密。所以有如下sql:
insert into mysql.user values('帐号名',PASSWORD('设置的帐号密码'));


但是,mysql4.1版本之前有些不同。当你使用php扩展库连接的时候。

old_password()就是按照之前的版本设置设置mysql密码。

可否这样理解:

mysql4.1版本之前的密码加密方式与之后的版本加密方式不同。因而就需要使用这个函数?


想想,新版本的为什么改进了原来的16个字符加密,而使用41个字符串的形式加密密码明文?
可以认为是出于安全考虑(手册中介绍为什么提供old_password(),隐约提到安全考虑)。字符越多越难破解?减少密码被截获的风险


mysql4.1版本之前与>=4.1版本,区别就是password()函数被重写了。生成的加密串长度一个是16位,一个为41位。


总结:mysql提供一个old_password函数与my.conf中old_passwords配置选项,就是为了使密码兼容4.1之前版本的加密方式。
比如:假如数据从4.0迁移到5.1版本服务器上。那么user表中密码方式不一样。如果开启这个选项,则还是按照4.0的版本进行加密。

疑问:但是实际用处多大?




网上提到的解决办法
SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

含义为:对于需要使用mysql4.1版之前的客户端的用户,将密码恢复为4.1版之前的风格。
因为old_password()函数生成的密码的加密方式是,按照4.1之前的版本生成。所以上面就是按照<=4.0的版本的加密方式保存密码。

SET PASSWORD FOR '帐号' = 密码加密后的值;#为某某帐号设置密码为xxx




不过,我遇到的实际情况不一样的,只是也报这种错误。

环境:mysql 是5.0  
PHP使用5.3的话才报出这种错误。
如果php切换到5.2则问题消失。
分析:说明。如果用5.3版本中的mysql扩展去连接5.0的mysql服务器,出现了问题。是扩展的问题。
php中的mysql扩展实质上就是一个mysql客户端。是客户端不兼容的问题??


已经知道是mysql版本原因。生成密码的时候4.1版本是生成16个字符。后续版本是生成总计41(生成40个后在前面统一加上一个*)个字符了。
既然如此,我的情况mysql的版本是5.0版本,所以生成的应该 41个字符。那么,即使我使用的是php.5.3版本的扩展,也不会有影响才对?









对于这个函数的解释,手册翻译没有翻译好,词不达意,摘录台湾解释版本:

OLD_PASSWORD(str)

    str 傳入的明文密碼


回傳MySQL 4.1版之前的PASSWORD結果。
OLD_PASSWORD()會被增加到MySQL函數是為了改善安全性造成的問題。OLD_PASSWORD()回傳MySQL 4.1版之前的PASSWORD結果,同時允許你使用任何4.1之前的連接程式使用原本的密碼連線到你的MySQL伺服器,避免他們被中斷服務。





疑问:调用OLD_PASSWORD函数会对mysql服务器密码机制造成什么影响吗?或者会改变原来的密码加密方式。导致其他客户端连接出现问题?

不会。old_password(),只是对当前密码明文使用何种方式加密(加密16个字符)。其实在4.1版本之前,密码都是以16个字符加密保存的。

而my.conf中的配置选项"old_passwords = 1;"可以配置使用旧的(表示4.1版本之前)密码加密方式生成密码保存到user表。影响的地方在于:

当使用grant(该命令会涉及到创建密码)分配帐号。
或者使用"set password for '帐号' = password('密码明文');"的时候。因为受到my.conf配置的影响,password()实际上是使用旧的方式加密,即加密成16个字符。



疑问:我使用php5.2版本里面的mysql扩展连接"旧的加密方式"的mysql服务器。为什么没有报错,能够连接?

与客户端有关?

确定的事情为:客户端尝试连接mysql服务器的时候。mysql服务器会将从客户端接收到密码明文,调用password(),生成加密hash值(通俗点就是加密后的字符),然后与mysql.user表中的Password字段对比。
所以,为什么删掉my.conf中的"old_passwords=1",有些人就连接出错。原因为:之前该配置是打开的。所以生成的密码都是16个字符保存在user表中。现在删掉后,客户端连接,调用的password()函数是生成41个字符,所以就对比不上了。
mysql为什么不是提示密码错误?
mysql对比user表发现里面保存的是16个字符,与生成的41个字符有长度上的区别,所以告诉你是版本上的原因。
疑问:既然mysql能够明确知道16个字符与41个字符的区别。说明已经知道是什么原因了。为什么没有自动调用旧的加密方式对客户端的明文密码加密?可能是安全考虑。



上面一部分理解错误的:
客户端连接服务器的时候,是客户端调用password()函数生成密码hash值。而非服务器。所以很容易明白为什么与客户端版本有关系了。
客户端版本是5.1,可以连接到4.1之前的服务器。
但是4.1之前的版本的客户端却无法连接到5.1版本的服务器。

基于上述情况,所以很容易确定,"更高版本的mysql客户端是能够向下兼容连接mysql4.1之前的服务器的"。
实际上变成了,mysql服务器与mysql客户端之间的版本兼容问题了。




疑问:既然客户端是向下兼容的,为什么5.3php的客户端无法连接就加密方式的mysql呢?

要理清楚,客户端之间的关系是什么?
发现原因是其他的。因为php5.3版本中的mysql扩展完全不同:集成在php源码中发布的,因而属于php一部分



php5.3版本用的扩展库是mysqlnd 5.0.7-dev - 091210 - $Revision: 304625 $ 。
而5.2版本用的扩展库为5.0

关于其说明:
PHP5.3 和 PHP6 中,均采用了 mysqlnd 做为 mysql 数据库的默认驱动.

mysqlnd 是在 PHP 源码树中集成, 与原先的 libmysql 不同, mysqlnd 与内核联系更紧密.


看来上面说明,已经确定原因了。php中的mysql扩展确实能够向下兼容,能正常访问mysql4.1之前的服务器(否则php5.2的5.0mysql扩展就无法访问基于old_password加密方式的mysql服务器了)。

但是,由于php5.3中嵌入的扩展完全是另一种架构了。所以无法连接。

#############################







####################################

测试代码:

#SELECT PASSWORD('123'),LENGTH(PASSWORD('123'));

#SET SESSION old_passwords=1;

SELECT PASSWORD('123'),LENGTH(PASSWORD('123'));

SHOW GLOBAL VARIABLES LIKE '%old_passwords%'##查看my.conf中配置项设置值。注意:不加gloabl,则默认是取得session变量的值(当前连接生效的值)



实际处理总结:把密码改成16位,还是32位形式保存到user表中去。有多个客户端在连接mysql。那么就意味着有多个扩展。那么只要保证php中的扩展能够正常连接即可。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7天前
|
关系型数据库 MySQL 数据库
mysql卸载、下载、安装(window版本)
mysql卸载、下载、安装(window版本)
|
1月前
|
关系型数据库 MySQL 数据库
MySQL忘记root密码、远程无法连接的解决方法
MySQL忘记root密码、远程无法连接的解决方法
|
2月前
|
运维 Unix Linux
Linux系统 PHP安装expect扩展详解
Linux系统 PHP安装expect扩展详解
39 5
|
27天前
|
关系型数据库 MySQL 数据库
django4版本提示 django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.26)
在学习Django时,用户遇到`django.db.utils.NotSupportedError`,提示需要MySQL 8.0.25或更高版本,但其系统上是5.7.26。为解决这个问题,用户决定不升级MySQL,而是选择注释掉Django源码中的数据库版本检查。通过Python命令行找到Django安装路径,进入`db/backends/base/base.py`,注释掉`self.check_database_version_supported()`函数
72 0
|
17天前
|
SQL 关系型数据库 MySQL
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(8.0版本升级篇)
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(8.0版本升级篇)
83 0
|
24天前
|
SQL 关系型数据库 MySQL
阿里云MySQL数据库价格、购买、创建账号密码和连接数据库教程
阿里云数据库使用指南:购买MySQL、SQL Server等RDS实例,选择配置和地区,完成支付。创建数据库和账号,设置权限。通过DMS登录数据库,使用账号密码访问。同地域VPC内的ECS需将IP加入白名单以实现内网连接。参考链接提供详细步骤。
363 3
|
1天前
|
PHP
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
|
6天前
|
NoSQL Linux PHP
php添加redis扩展 linux和windos图文详解 l
php添加redis扩展 linux和windos图文详解 l
3 0
|
26天前
|
PHP 数据安全/隐私保护
PHP页面如何实现设置独立访问密码
PHP网页如果需要查看信息必须输入密码,验证后才可显示出内容的代码如何实现? 对某些php页面设置单独的访问密码,如果密码不正确则无法查看内容,相当于对页面进行了一个加密
12 2
PHP页面如何实现设置独立访问密码
|
1月前
|
关系型数据库 MySQL 数据库
【MySQL】——忘记密码后如何修改密码
【MySQL】——忘记密码后如何修改密码
39 0