最近在修一个程序,对接的是杰奇的数据库,它有个明显的问题就是登录注册是失效的,这个问题在1.X的版本并不会出现,我折腾了一下发现是杰奇2.4的密码字段加密规则有了变化,导致了自然而然出现的问题。所以,研究一下新的密码加密的机制,也就有了一些必要的感觉。毕竟最近还在学习mui开发,感觉不搞个app出来对不起自己唉,但是app的话又要拜托朋友写接口,登录注册本就是个大问题啊。
呼~
依旧是老规矩,如果感觉不太对,这篇文章就会删除。
我只是基于网上流传的版本进行兴趣爱好的研究,如果大家要正规做站请尽量支持官方正版,那个最安全,也最靠谱。
折腾开始
首先我找了一下杰奇2.4的密码是怎么加密的。
比如class/user.php文件,存在如下代码:
public function encryptPass($pass)
{
$salt = $this->getVar('salt', 'n');
if (!empty($salt)) {
return md5(md5($pass) . $salt);
} else {
return md5($pass);
}
}
可以很明显的看到,密码字段的加密叠了两层,在第一次加密的基础上,接合一个$salt字段,再进行一次md5。
但是我们打开杰奇2.3和以下的版本看,代码简单的吓人,是这样的:
public function encryptPass($pass)
{
return md5($pass);
}
感觉确实是一次更加安全的,用来防止撞库的升级啊,那么我就更加好奇了,我想看看3.0的,所以在兴趣使然的前提下,我拜托哥们给了我一个单独解密的user.php文件,对于杰奇3.0,它所在的位置是/cms/modules/system/class,再次找到同样的代码区域。
public function encryptPass($pass)
{
$salt = $this->getVar("salt", "n");
if (!empty($salt)) {
return md5(md5($pass) . $salt);
} else {
return md5($pass);
}
}
emmmm,好吧,是一模一样的,说明至少3.0版本这里的加密方式仍然相同。
好了,然后回到一个实际的问题$salt字段是什么,从哪里获取到的,怎么来的。
其实user.php这个文件已经给了答案,可以看如下的代码:
$salt = substr(md5(uniqid(rand(), true)), -16);
$newUser->setVar("salt", $salt);
if (!isset($params["password"]) || strlen($params["password"]) == 0) {
$newUser->setVar("pass", "");
} else {
$newUser->setVar("pass", $this->encryptPass($params["password"], $salt));
}
在这个代码里,告诉了$salt是通过加密一个随机数,然后取指定的位数得到的,这个安全做得真心到位,关键的这一句一定要注意。
$salt = substr(md5(uniqid(rand(), true)), -16);
$salt是凭空生成的,然后扔进了数据库,数据里也摆在面前了。这个的案例可以参考老古小说网https://www.laoguu.com
所以一切豁然开朗,那就是注册的时候,生成$salt字段,先加密pass,然后和pass一起存入数据库。而登录的时候,就是直接先从数据库里取出$salt字段,加密传递的pass,和数据里的已经加密pass进行比对,就完成了登录注册验证的整个流程。
登录加密的简单范例:
$saltsql = $db->get_row("select * from jieqi_system_users where uname = '".$chname."'");
$salt = $saltsql['salt'];
$pass = md5(md5($chpass).$salt);
注册加密的简单范例
$salt = substr(md5(uniqid(rand(), true)), -16);
$regpass = md5(md5($regpass).$salt);
OK,思路解析完成,继续我的app开发大业。