yii框架加密用户密码必须用generatepasswordhash()生成哈希、validatepassword()验证,禁用hashdata()、encrypt()及手写password_hash();默认采用bcrypt算法($2y$开头、60字符),自动管理盐和迭代,确保不可逆与兼容性。

Yii 框架加密用户密码,必须用 generatePasswordHash() 生成哈希值,再用 validatePassword() 验证——别碰 hashData()、encrypt() 或手写 password_hash(),否则不是降级就是校验失败。
密码哈希必须用 generatePasswordHash + validatePassword
Yii 的密码存储不是“加密”,而是不可逆的强哈希。它默认调用 PHP 的 crypt() 实现 bcrypt($2y$ 开头,60 字符),自动管理随机 salt 和 10 万次迭代。
-
generatePasswordHash()输出直接存数据库,无需拆解或额外处理 -
validatePassword($input, $hash)会自动识别$2y$、$2a$、$1$等前缀,分发到对应验证逻辑;自己调password_verify()可能漏掉旧数据兼容路径 - 传错参数(比如把
$hash当$salt单独传)会导致跳过校验,永远返回false - 如果服务器禁用了
crypt(),会抛NotSupportedException,不会静默退化成弱哈希
encryptByKey 不是给密码用的,别混淆场景
有人看到 encryptByKey() 就想拿它“加密密码”,这是典型误用。该方法是 AES 对称加解密,目标是「可还原」,而密码必须「不可逆」。
- 密码哈希走
generatePasswordHash();身份证、手机号等需还原的敏感字段,才考虑encryptByKey() -
encryptByKey()要求密钥严格 32 字节(AES-256)或 16 字节(AES-128),传错长度可能静默降级或报InvalidParamException - 密文是二进制,入库或传参前必须
base64_encode();解密前得先base64_decode() -
encrypt()和decrypt()是 Yii 内部用于 Cookie 签名的私有方法,公开调用会破坏密钥隔离,跨版本无法解密
hashData 仅适用于防篡改签名,不是密码工具
hashData() 本质是 HMAC-SHA256,输出固定长度摘要,用于校验数据是否被篡改(如带时效的下载链接 token),但它不加盐、不迭代、可被暴力穷举——绝对不能当密码哈希用。
- 必须显式传一个保密的
$secretKey作为 salt,且该 key 要全局固定、环境隔离(推荐从 env 加载) - 它不生成随机 salt,也不做 PBKDF2 迭代,对短口令毫无防护力
- 常见误用:用
hashData('123', 'mykey')存密码 → 攻击者跑一遍字典就破解 - 正确用途示例:
$token = $security->hashData("user:123|".time(), $_ENV['TOKEN_SALT']);
最易被忽略的一点:generatePasswordHash() 生成的哈希字符串里已完整封装了算法、cost、salt 和 hash 值,你唯一要做的就是原样存、原样传给 validatePassword() ——任何手动截取、base64 解码、正则匹配 salt 的操作,都在破坏 Yii 的安全抽象。











