MySQL是如何做到安全登陆
⾸先Mysql的密码权限存储在mysql.user表中。我们不关注鉴权的部分,我们只关⼼⾝份认证,识别⾝份,后⾯的权限控制是很简单的事情。
在mysql.user表中有个authentication_string字段,存储的是密码的两次sha1值。你可以⽤下⾯的语句,验证和mysql.user表中存储的是⼀致的。 select sha1(UNHEX(sha1(‘password’)))
以上就是服务端关于密码的存储,接下来是认证过程。
Mysql采⽤的是⼀种challenge/response(挑战-应答)的认证模式。 第⼀步:客户端连接服务器
第⼆步:服务器发送随机字符串challenge给客户端 第三步:客户端发送username+response给服务器
其中response=HEX(SHA1(password) ^ SHA1(challenge + SHA1(SHA1(password)))) 第四步:服务器验证response。
服务器存储了SHA1(SHA1(password)))
所以可以计算得到SHA1(challenge + SHA1(SHA1(password))))
那么SHA1(password)=response^ SHA1(challenge + SHA1(SHA1(password)))) 最后再对SHA1(password)求⼀次sha1和存储的数据进⾏⽐对,⼀致表⽰认证成功。
我们分析它的安全性:
抓包可以得到response,但是每次认证服务器都会⽣成challenge,所以通过抓包⽆法构造登陆信息。
数据库内容被偷窥,数据库记录的是sha1(sha1(password)),不可以得到sha1(password)和明⽂密码,所以⽆法构造response,同样⽆法登陆。
当然如果被抓包同时数据库泄密,就可以得到sha1(password),就可以仿冒登陆了。
这种认证⽅式其实是有⼀个框架标准的,叫做SASL(Simple Authentication and Security Layer ),专门⽤于C/S模式下的⽤户名密码认证。原理就是服务器发送⼀个challenge(质询)给客户端,客户端返回的response证明⾃⼰拥有密码,从⽽完成认证的过程,整个过程不需要密码明⽂在⽹络上传输。
基于SASL协议有很多实现,mysql的就是模仿的CRAM-MD5协议,再⽐如SCRAM-SHA1协议,是mongdb、PostgreSQL使⽤的认证⽅式。
在JDK中专门有⼀套SASL的API,⽤于实现不同的SASL认证⽅式。