php加密解密
PHP的密解密加密解密,说白了就是密解密两件事:把数据变成别人看不懂的乱码,以及把乱码变回原样。密解密但这里头门道不少,密解密坑也多。密解密我见过太多新手直接拿md5当加密用,密解密结果存密码是密解密够用了,可一旦需要还原数据就傻眼——md5根本不可逆,密解密它连加密都算不上,密解密顶多是密解密个指纹。
真正的密解密PHP加解密,绕不开openssl扩展。密解密比如你要加密一段用户手机号,密解密用AES-128-CBC算法,密解密代码就几行:
$key = '32位随机密钥'; $iv = openssl_random_pseudo_bytes(16); $encrypted = openssl_encrypt($data,密解密 'AES-128-CBC', $key, 0, $iv);
看着简单对吧?但坑全在细节里。$iv(初始化向量)必须随机生成,每次加密都换新的,不然同样的明文会产生同样的密文,等于给黑客递刀子。解密时又得把$iv和密文一起存,有人图省事把$iv硬编码成固定字符串,那安全性直接砍半。
另一个坑是密钥管理。PHP代码里写死密钥是常态,但代码一旦泄露,密钥跟着完蛋。我见过某电商平台把密钥放在配置文件里,结果.git仓库泄露,几万条用户手机号被拖库。正确做法是把密钥放在环境变量或专门的密钥管理服务里,代码里只留个引用。
再说说非对称加密。RSA在PHP里用起来更麻烦,公钥加密私钥解密,私钥得放服务器外,公钥可以随便给前端。但性能差,加密几百字节的数据还行,加密大文件能把你CPU跑满。所以实际项目中常见组合是:用RSA加密AES的密钥,再用AES加密实际数据,这叫混合加密,对接支付接口时经常这么干。
还有一类需求是防篡改,不是防偷看。比如生成一个带签名的链接,URL里带参数,服务端验签防止参数被改。PHP里用hash_hmac就行,但很多人图方便用简单的md5拼接盐,结果被长度扩展攻击打穿。用hash_hmac('sha256', $data, $secret)至少能挡住大部分野路子攻击。
咱们得说点实话:PHP的加解密函数虽然多,但坑比功能更丰富。openssl_encrypt默认填充是PKCS7,有些老代码用openssl_public_encrypt时忘了指定填充方式,导致跨语言解密时对不上。还有base64编码问题,密文里可能带斜杠和加号,放进URL得urlencode,否则参数直接被截断。
我见过最离谱的案例,是有人用base64_encode当加密,觉得把明文变成长串就安全了。结果前端JS用atob一解,用户信息全裸奔。这不算加密,只是编码,就像把字写成拼音,懂规则的人照样读懂。
说回实用建议。如果你只是想存密码,别折腾加解密,用password_hash和password_verify,PHP官方都替你优化好了,自带盐和算法升级空间。如果你真要加密可逆数据,先想清楚:密钥怎么轮换?泄露了怎么撤销?数据在日志里会不会残留明文?这些比加密函数本身重要得多。
最后提醒一句:PHP的openssl扩展在7.1之后默认启用,但老项目可能还在用mcrypt,那玩意早被移除了。升级PHP版本时,顺手把加密代码也重构一遍,别等到线上跑着跑着突然报函数不存在,那场面可不好收拾。
