如何在CodeIgniter中比对加密存储的登录密码?(加密结果不一致)
解决密码加密后比对失败的问题
哦,这个问题我太熟悉了——你踩了对称加密不适合存储密码的坑!
问题根源
你用的$this->encrypt->encode()是CodeIgniter的对称加密方法,它每次加密同一个密码时,会自动生成随机的初始化向量(IV)或盐,所以每次输出的密文都不一样。这本来是对称加密的安全特性,但用来存密码就麻烦了:登录时你重新加密输入的密码,得到的密文和数据库里存的完全不同,自然比对失败。
密码存储的正确姿势是用单向哈希算法——它只能从明文生成哈希,无法反向解密,而且验证时不需要重新生成哈希,而是用专门的验证函数来匹配明文和存储的哈希。
解决方案:改用PHP原生的密码哈希/验证函数
PHP自带的password_hash()和password_verify()是目前最安全、最省心的密码处理方案,直接替换你的现有代码即可:
1. 注册/修改密码时,生成哈希并存库
$first_password = $this->input->post('password'); // 生成安全的哈希密码,自动处理盐值 $hashed_password = password_hash($first_password, PASSWORD_DEFAULT); // 后续将$hashed_password存入oss_user表的password字段
2. 登录验证时,取出哈希并验证
修改你的模型代码,先根据用户名取出用户的哈希密码,再用password_verify()验证:
public function validate_login($username, $input_password){ // 先查询对应用户的信息 $q = $this->db->where(['username' => $username])->get('oss_user'); if($q->num_rows() === 1){ $user = $q->row(); // 用password_verify验证输入密码和存储的哈希是否匹配 if(password_verify($input_password, $user->password)){ return $user; // 验证成功,返回用户数据 } } // 用户不存在或密码错误,返回false return false; }
关键注意事项
- 数据库的
password字段长度要足够:PASSWORD_DEFAULT生成的哈希是60字符,建议设置为VARCHAR(255),预留未来算法升级的空间。 - 不要手动加盐:
password_hash()会自动生成安全的随机盐,手动加盐反而可能降低安全性。 - 放弃MD5、SHA1这类旧算法:它们的碰撞风险高,容易被暴力破解,bcrypt(
password_hash默认算法)的安全性要高得多。
如果坚持要用CodeIgniter的工具,也可以用它的password_helper,但本质上还是封装了PHP原生的密码函数,用法和上面一致。
内容的提问来源于stack exchange,提问作者Adi King
相关产品推荐
相关产品推荐

