PHP文件内容加密怎么做_读取加密写入解密完整流程【详解】

3次阅读

php文件加密应使用openssl_encrypt/decrypt配合aes-256-cbc,密钥需sha256二进制化,iv每次随机生成并随密文存储,密文须base64编码,严禁硬编码密钥或复用iv。

PHP文件内容加密怎么做_读取加密写入解密完整流程【详解】

PHP 文件内容加密用 openssl_encrypt,别碰 mcrypt

PHP 7.2+ 已彻底移除 mcrypt 扩展,硬启用会报 Call to undefined function mcrypt_encrypt()。现在标准做法是 openssl_encrypt + openssl_decrypt,配合 AES-128-CBC 或 AES-256-CBC(推荐后者)。密钥必须是固定长度(如 32 字节对应 AES-256),不能直接用字符串当密钥——得用 hash('sha256', $raw_key, true) 转成二进制密钥。

常见错误:用 md5($key) 当密钥(长度够但不可控)、IV 复用(同一个 IV 加密多个文件会导致模式泄露)、没 base64 编码密文就写入文件(二进制内容会损坏或截断)。

  • IV 必须每次随机生成,且和密文一起保存(比如前 16 字节),解密时原样取出
  • 加密后务必 base64_encode() 再写入文件;解密前先 base64_decode()
  • 不要把密钥写死在代码里,更不要拼接进文件路径或日志

读取加密文件并解密的三步:读、解、验

读取时不能假设文件一定存在或格式正确。典型失败场景:文件被截断、base64 解码失败、openssl_decrypt 返回 false(此时 openssl_error_string() 可查具体原因,比如密钥错、IV 长度不对、填充异常)。

  • 先用 file_get_contents() 读全文件,再 base64_decode(),失败则终止
  • 拆出前 16 字节为 IV,剩余为密文;IV 长度必须严格等于 openssl_cipher_iv_length('AES-256-CBC')
  • 解密后建议校验明文结构(比如 json 是否能 json_decode($plain, true) 成功),防密钥误用导致乱码被当成有效数据

写入加密文件时最容易漏掉的两个细节

一是没处理 padding。AES-CBC 要求明文长度是块大小(16 字节)的整数倍,openssl_encrypt 默认用 PKCS#7 填充,但如果你手动截断或拼接内容,可能破坏填充结构;二是权限控制。加密不是访问控制——文件仍可被读,只是内容不可读。如果 PHP 进程有权限读写,攻击者拿到文件+密钥(比如从配置中泄露)就能解密。

立即学习PHP免费学习笔记(深入)”;

  • 写入前确保目录可写、磁盘空间足够,否则 file_put_contents() 静默失败
  • 加密后的文件后缀别用 .php.inc,避免 Web 服务器意外解析执行
  • 敏感文件写入后建议 chmod(0600, $path) 限制权限,尤其在共享主机环境

为什么不用 password_hashhash_hmac 做文件加密

password_hash 是单向哈希,不可逆,只适合存密码;hash_hmac 是消息认证码,用于验证完整性,不提供机密性。文件加密必须满足「可逆」+「抗窃听」,只有对称加密函数满足。有人试过用 openssl_encryptOPENSSL_RAW_DATA 标志省去 base64,结果文件里出现 字符,导致部分函数(如 file()explode())提前截断——这种二进制边界问题,调试起来比密钥错误还隐蔽。

真正麻烦的从来不是加解密函数调用本身,而是密钥生命周期管理、IV 安全分发、以及加密后文件如何被其他系统安全消费——这些环节一旦松动,前面所有加密都形同虚设。

text=ZqhQzanResources