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);