diff --git a/init.php b/init.php
index 13862a32..bd80c475 100644
--- a/init.php
+++ b/init.php
@@ -6,7 +6,7 @@
*/
define('SYSTEM_FN', '百度贴吧云签到');
-define('SYSTEM_VER', '5.00');
+define('SYSTEM_VER', '5.01');
define('SYSTEM_VER_NOTE', '');
define('SYSTEM_ROOT', dirname(__FILE__));
define('PLUGIN_ROOT', dirname(__FILE__) . '/plugins/');
diff --git a/lib/class.P.php b/lib/class.P.php
index b0962289..05a2176e 100644
--- a/lib/class.P.php
+++ b/lib/class.P.php
@@ -34,15 +34,53 @@ public function __construct($salt = '')
}
/**
- * 对数据(通常是密码)进行不可逆加密
+ * [弃用] 对数据(通常是密码)进行不可逆加密
* @param string $pwd 密码
* @return string 加密的密码
*/
- public function pwd($pwd)
+ public function legacy_pwd($pwd)
{
return eval('return ' . option::get('pwdmode') . ';');
}
+ /**
+ * 对数据(通常是密码)进行不可逆加密
+ * @param string $pwd 密码
+ * @param boolean $with_legacy 是否包含旧密码(不支持 `password_hash()` 时无效)
+ * @return string|object 新密码(和带旧版密码的 array)
+ */
+ public function pwd($pwd, $with_legacy = false)
+ {
+ if (function_exists("password_hash")) {
+ $newHash = password_hash($pwd, PASSWORD_BCRYPT, ["cost" => 12]);
+ if ($with_legacy) {
+ $legacy_hash = $this->legacy_pwd($pwd);
+ return [
+ "new" => $newHash,
+ "legacy" => $legacy_hash,
+ ];
+ } else {
+ return $newHash;
+ }
+ } else {
+ return $this->legacy_pwd($pwd);
+ }
+ }
+
+ /**
+ * 校验密码是否合法
+ * @param string $pwd 密码
+ * @return boolean 密码是否合法
+ */
+ public function pwd_verify($pwd, $hash)
+ {
+ if (function_exists("password_verify") && password_verify($pwd, $hash)) {
+ return true;
+ }
+ // legacy
+ return $hash === $this->legacy_pwd($pwd);
+ }
+
/**
* 对数据进行可逆加密
* @param string $str 原文
diff --git a/lib/globals.php b/lib/globals.php
index 8976c9ab..d90801c6 100644
--- a/lib/globals.php
+++ b/lib/globals.php
@@ -13,7 +13,7 @@
$con_uid = isset($_COOKIE['uid']) ? sqladds($_COOKIE['con_uid']) : '';
$con_pw = isset($_COOKIE['pwd']) ? sqladds($_COOKIE['con_pwd']) : '';
$con_p = $m->once_fetch_array("SELECT * FROM `" . DB_NAME . "`.`" . DB_PREFIX . "users` WHERE `id` = '{$con_uid}' LIMIT 1");
- if (empty($con_p['id']) || $con_pw != substr(sha1(EncodePwd($con_p['pw'])), 4, 32)) {
+ if (empty($con_p['id']) || hash_hmac('sha256', $con_p['pw'], $con_p['id'] . $con_p['pw']) !== $con_pw) {
setcookie("con_uid", '', time() - 3600);
setcookie("con_pwd", '', time() - 3600);
} else {
@@ -42,7 +42,7 @@
}
doAction('globals_1');
$p = $m->fetch_array($osq);
- if ($pw != substr(sha1(EncodePwd($p['pw'])), 4, 32)) {
+ if (hash_hmac('sha256', $p['pw'], $p['id'] . $p['pw']) !== $pw) {
setcookie("uid", '', time() - 3600);
setcookie("pwd", '', time() - 3600);
ReDirect("index.php?mod=login&error_msg=" . urlencode('Cookies 所记录的账号信息不正确,请重新登录(#2)') . "");
@@ -135,7 +135,7 @@
die;
}
$p = $m->fetch_array($osq);
- if (EncodePwd($pw) != $p['pw']) {
+ if (!VerifyPwd($pw, $p['pw'])) {
ReDirect("index.php?mod=login&error_msg=" . urlencode('密码错误'));
die;
} else {
@@ -147,11 +147,11 @@
$cktime = 999999;
}
setcookie("uid", $p['id'], time() + $cktime);
- setcookie("pwd", substr(sha1(EncodePwd(EncodePwd($pw))), 4, 32), time() + $cktime);
+ setcookie("pwd", hash_hmac('sha256', $p['pw'], $p['id'] . $p['pw']), time() + $cktime);
ReDirect('index.php');
} else {
setcookie("uid", $p['id']);
- setcookie("pwd", substr(sha1(EncodePwd(EncodePwd($pw))), 4, 32));
+ setcookie("pwd", hash_hmac('sha256', $p['pw'], $p['id'] . $p['pw']));
ReDirect('index.php');
}
}
diff --git a/lib/sfc.functions.php b/lib/sfc.functions.php
index 46e701dd..943548a0 100644
--- a/lib/sfc.functions.php
+++ b/lib/sfc.functions.php
@@ -24,13 +24,25 @@ function getIp()
/**
* 加密密码
* @param string $pwd 密码
- * @return string 加密的密码
+ * @param boolean $with_legacy 是否包含旧密码
+ * @return string|object 新密码和旧版密码
*/
-function EncodePwd($pwd)
+function EncodePwd($pwd, $with_legacy = false)
{
+ $p = new P();
+ return $p->pwd($pwd, $with_legacy);
+}
+/**
+ * 校验密码
+ * @param string $pwd 密码
+ * @param string $hash hash 值
+ * @return boolean 密码是否合法
+ */
+function VerifyPwd($pwd, $hash)
+{
$p = new P();
- return $p->pwd($pwd);
+ return $p->pwd_verify($pwd, $hash);
}
/**
diff --git a/setup/install.template.sql b/setup/install.template.sql
index c4904b1c..ef7edd13 100644
--- a/setup/install.template.sql
+++ b/setup/install.template.sql
@@ -88,7 +88,7 @@ INSERT INTO `{VAR-PREFIX}options` VALUES ('cron_sign_again', 'a:2:{s:3:\"num\";i
INSERT INTO `{VAR-PREFIX}options` VALUES ('sign_hour', '0');
INSERT INTO `{VAR-PREFIX}options` VALUES ('mail_secure', 'none');
INSERT INTO `{VAR-PREFIX}options` VALUES ('freetable', 'tieba');
-INSERT INTO `{VAR-PREFIX}options` VALUES ('core_version', '4.98');
+INSERT INTO `{VAR-PREFIX}options` VALUES ('core_version', '5.01');
INSERT INTO `{VAR-PREFIX}options` VALUES ('vid', '10000');
INSERT INTO `{VAR-PREFIX}options` VALUES ('update_server', '0');
#INSERT INTO `{VAR-PREFIX}options` VALUES ('toolpw', '{VAR-TOOLPW}');
@@ -145,7 +145,7 @@ DROP TABLE IF EXISTS `{VAR-PREFIX}users`;
CREATE TABLE `{VAR-PREFIX}users` (
`id` int(30) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
- `pw` char(32) NOT NULL,
+ `pw` TEXT NOT NULL,
`email` varchar(40) NOT NULL,
`role` varchar(10) NOT NULL DEFAULT 'user',
`t` varchar(20) NOT NULL DEFAULT 'tieba',
diff --git a/setup/update5.00to5.01.php b/setup/update5.00to5.01.php
new file mode 100644
index 00000000..7051191b
--- /dev/null
+++ b/setup/update5.00to5.01.php
@@ -0,0 +1,17 @@
+= '5.01') {
+ msg('您的云签到已升级到 V5.01 版本,请勿重复更新
请立即删除 /setup/update5.00to5.01.php');
+}
+$m->query("ALTER TABLE `" . DB_PREFIX . "users` CHANGE `pw` `pw` TEXT;", true);
+
+option::set('core_version', '5.01');
+unlink(__FILE__);
+msg('您的云签到已成功升级到 V5.01 版本,请立即删除 /setup/update5.00to5.01.php,谢谢', SYSTEM_URL);