如何对PHP读取的明文用户信息进行加密以提升安全性
简便改造方案(无需额外依赖,基于PHP原生OpenSSL扩展)
首先做前置基础加固:
- 先将原明文文件
UserInfo.txt的访问权限锁死,Linux下执行chmod 600 UserInfo.txt,所有者修改为Web服务运行用户(如www-data),处理完加密后建议删除原明文文件,避免泄露。 - 所有涉及密钥、密文的文件都要存放在Web根目录之外,禁止被外网直接访问。
第一步:生成密钥并加密原凭证
先运行一次一次性加密脚本,生成加密密钥和密文文件:
<?php // 加密算法选用AES-256-GCM,安全性和性能都能满足常规需求 $cipher = 'aes-256-gcm'; // 生成随机256位密钥,存到web根目录外的路径,示例为../secret.key $key = openssl_random_pseudo_bytes(openssl_cipher_key_length($cipher)); file_put_contents('../secret.key', $key); chmod('../secret.key', 0600); // 锁死密钥文件权限,仅所有者可读可写 // 读取原明文凭证 $fh = fopen('../UserInfo.txt', 'r'); $user = trim(fgets($fh)); $pass = trim(fgets($fh)); fclose($fh); // 加密凭证 $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher)); $tag = ''; $encryptedUser = openssl_encrypt($user, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag); $encryptedPass = openssl_encrypt($pass, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag); // 把iv、tag、加密后的用户名密码按规则拼接后存到密文文件,示例为../UserInfo.enc file_put_contents('../UserInfo.enc', $iv . $tag . $encryptedUser . '|||' . $encryptedPass); chmod('../UserInfo.enc', 0600); // 执行完此脚本后请删除原UserInfo.txt和本加密脚本,避免明文泄露 ?>
第二步:改造原有getCredentials函数
function getCredentials($encPath = '../UserInfo.enc', $keyPath = '../secret.key') { $credentials = null; $cipher = 'aes-256-gcm'; try { $key = file_get_contents($keyPath); $encContent = file_get_contents($encPath); if ($key && $encContent) { // 拆分存储的iv、tag、加密内容 $ivLen = openssl_cipher_iv_length($cipher); $iv = substr($encContent, 0, $ivLen); $tag = substr($encContent, $ivLen, 16); // GCM算法tag固定为16位 $encData = substr($encContent, $ivLen + 16); list($encUser, $encPass) = explode('|||', $encData); // 解密得到明文凭证 $userName = openssl_decrypt($encUser, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag); $password = openssl_decrypt($encPass, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag); if ($userName && $password) { $credentials = (object)array( "userName" => trim($userName), "password" => trim($password), "keepAlive" => false ); } } } catch (Exception $ignored) { } return $credentials; }
额外安全补充
- 调用其他Web应用做身份验证时,必须使用HTTPS协议发起请求,避免传输过程中凭证泄露
- 密钥可以定期更换,更换时重新运行加密脚本生成新的密文和密钥即可
- 不要将密钥硬编码在项目代码里,也不要提交到代码仓库
内容的提问来源于stack exchange,提问作者Grammy
相关产品推荐
相关产品推荐

