密码存储唯一正确方式是password_hash()与password_verify();加密通信优先选sodium_crypto_secretbox,次选aes-256-gcm;禁用md5、sha1、mcrypt及cbc模式;密钥、iv/nonce须安全生成且不可硬编码。

直接说结论:别用 md5、sha1 存密码,别用 mcrypt(已废弃),PHP 7.2+ 新项目优先选 sodium_crypto_secretbox;若需兼容旧系统或必须用 OpenSSL,则选 AES-256-GCM,而非 CBC 模式。
password_hash() 是密码存储的唯一正确姿势
密码不是“要解密的数据”,而是“需要验证是否匹配”。任何试图可逆加密密码的做法都错了。
-
password_hash()自动生成盐、选择算法(默认PASSWORD_ARGON2ID或PASSWORD_BCRYPT)、输出完整字符串(如$argon2id$v=19$m=65536,t=4,p=1$...),全部存进数据库即可 -
password_verify($input, $hash)自动提取盐和参数,不暴露时序差异;切勿用==或strcmp比较 - 不要自己拼接盐、不要用
md5($pass.$salt)、不要调用hash('sha256', ...)—— 这些都不抗暴力破解,也不防彩虹表
openssl_encrypt/decrypt 必须配 GCM 模式才安全
AES-256-CBC 本身不防篡改,单独使用等于裸奔。GCM 模式把加密和认证合二为一,解密失败时直接返回 false,而不是静默出错。
- 密钥长度必须是 32 字节:
openssl_random_pseudo_bytes(32),不能用字符串硬编码(如"my-secret-key-32") - IV 长度由算法决定:
openssl_cipher_iv_length('aes-256-gcm')返回 12,每次加密必须新生成且唯一 - GCM 加密会输出带认证标签的密文,需额外传入
&$tag引用参数:openssl_encrypt($data, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag) - 解密时必须同时提供
$tag:openssl_decrypt($ciphertext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag),缺一不可
sodium_crypto_secretbox 是 PHP 7.2+ 的默认推荐
它比 OpenSSL 更难用错:nonce 长度固定为 24 字节、自动处理认证、API 极简、无需手动管理填充或标签。
- 确认扩展已启用:
extension_loaded('sodium'),PHP 7.2+ 默认内置,不用额外安装 - 密钥生成必须用
sodium_crypto_secretbox_keygen(),不能用random_bytes(32)替代(虽然结果一样,但语义不清) - nonce 必须每次唯一,推荐
sodium_randombytes_buf(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES)(即 24 字节) - 加密后得到的是二进制密文,存储前务必
base64_encode();解密前先base64_decode(),否则返回false - 解密失败(如 nonce 错、密钥错、密文被改)一律返回
false,不抛异常,必须显式判断
密钥和 IV 绝对不能硬编码或写死在代码里
哪怕只是测试环境,也应从环境变量或配置中心加载。密钥泄露 = 全盘失守。
- 密钥建议通过
getenv('APP_ENCRYPTION_KEY')获取,生产环境用 Docker secrets、KMS 或 Vault 注入 - IV/nonce 可与密文一起存储(如 JSON 字段:
{"iv":"...", "ciphertext":"..."}),它不需要保密,但必须保证每次唯一 - 不要把密钥存在数据库、不要写进
.php文件、不要用file_get_contents('/path/to/key')—— 这些路径一旦被 Web 目录遍历或错误配置暴露,就全完了 - 如果用
base64编码密钥再存环境变量,解码后长度必须严格校验(如 AES-256 要 32 字节),避免因换行或空格截断导致解密失败
最容易被忽略的点:GCM 的 $tag 和 sodium 的 nonce 不是可选参数,它们是安全模型的一部分。少传一个,就等于放弃完整性校验 —— 攻击者可以随意翻转密文比特,而你还在 happily 解出看似正常的垃圾数据。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











