PHP动态加密解密函数实现:带完整性校验
针对Web开发中简单的数据安全传输需求,本文将介绍一个PHP自定义加密解密函数的实现原理与代码。该方案采用动态生成随机密钥前缀的方式,确保相同的输入内容每次加密后结果不同,从而防止重放攻击和字典查询。同时,函数内置了基于MD5的完整性校验字段,解密时会自动验证数据截断或修改的风险。
加密方案核心逻辑
传统的静态加密(如直接使用 base64_encode($text . $key))存在明显缺陷:同样的字符串永远得到相同的加密结果,容易被逆向分析。本函数通过以下策略提升安全性:
- 动态随机性:每次加密时在密文头部添加6个随机字符组成的
key_b,这使得即使明文和主密钥完全一致,生成的密文也会变化。 - 混淆处理:将明文、主密钥与随机前缀结合进行MD5哈希,再提取部分字符作为次级密钥,与明文进行异或(XOR)运算,增加破解难度。
- 完整性校验:在最终密文的最前端附加前8位校验码。这8位是“
随机前缀 + Base64编码后的异或结果”经过MD5后的哈希值。解密时若发现校验码不匹配,则拒绝返回数据。
第1步:定义加密参数结构
加密结果由两部分组成:
1. 8位校验头:用于防篡改。
2. 主体数据:包含6位随机前缀 + Base64编码后的异或密文。
这种结构设计使得解密过程必须严格遵循顺序:先剥离校验头,再验证真实性,最后剥离随机前缀并还原明文。
第2步:实现加密与解密通用函数
以下是完整的PHP代码实现。注意,该函数依赖于 md5、base64_encode/decode 等核心扩展,无需安装第三方库。
function encode_pass($tex,$key,$type="encode"){
// 定义字符集用于生成随机前缀
$chrArr=array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'0','1','2','3','4','5','6','7','8','9');
// --- 解码分支 ---
if($type=="decode"){
// 最小长度检查,因为至少有8位校验+6位随机前缀+Base64内容
if(strlen($tex)<14)return false;
// 提取前8位作为校验码
$verity_str=substr($tex, 0,8);
// 移除校验码,保留后续数据
$tex_data=substr($tex, 8);
// 计算理论上的正确校验码:对剩余数据整体做MD5取前8位
if($verity_str!=substr(md5($tex_data),0,8)){
// 完整性验证失败,可能是数据被篡改或解密密钥错误导致的内容乱码
return false;
}
}
// --- 密钥预处理 ---
if($type=="decode"){
// 如果是解密,随机前缀隐藏在密文第0-5位
$key_b=substr($tex_data,0,6);
// 获取真正的主体内容
$body_content=base64_decode(substr($tex_data, 6));
} else {
// 如果是加密,生成新的随机前缀
$key_b=$chrArr[rand()%62].$chrArr[rand()%62].$chrArr[rand()%62].$chrArr[rand()%62].$chrArr[rand()%62].$chrArr[rand()%62];
$body_content=$tex;
}
// 组合密钥流:随机前缀 + 用户传入的主密钥,然后MD5生成固定长度的密钥流
$rand_key_stream=$key_b.$key;
$rand_key_stream=md5($rand_key_stream);
// 执行异或操作生成/还原文本
$reslutstr="";
$texlen=strlen($body_content);
for($i=0;$i<$texlen;$i++){
// 逐字节异或
$reslutstr.=$body_content{$i}^$rand_key_stream{$i%32};
}
// --- 组装最终输出 (仅加密时需要) ---
if($type!="decode"){
// 对异或结果进行Base64编码
$encoded_body=base64_encode($reslutstr);
// 移除末尾可能存在的'='以节省空间(需确保Base64支持无填充解码,此处简化处理)
$encoded_body=trim($encoded_body,"==");
// 组装:6位随机前缀 + Base64内容
$combined=$key_b.$encoded_body;
// 计算校验头
$hash_header=substr(md5($combined), 0,8);
// 最终输出:校验头 + 组合数据
$reslutstr=$hash_header.$combined;
}
return $reslutstr;
}
// 测试用例
$key = "my_secret_key";
$text = "phpcode";
// 加密
$encrypted = encode_pass($text, $key);
echo "原始: {$text}
";
echo "加密: {$encrypted}
";
// 解密
$decrypted = encode_pass($encrypted, $key, 'decode');
echo "解密: {$decrypted}";
第3步:验证使用效果与安全性
在实际调用中,可以看到即使是相同的 $text 和 $key,每次运行脚本生成的 $encrypted 都会不同。这是因为 $key_b 是随机生成的。
当尝试对已被截断或修改的密文进行解密时,由于 substr(md5($tex_data),0,8) 的计算结果将无法匹配密文中的前8位,函数将直接返回 false。这有效防止了中间人篡改数据后再次解密的情况。
局限性与注意事项
- 非标准加密算法:此函数使用的是简单的异或与Base64组合,并非AES或RSA等国际标准算法。它主要目的是防止敏感信息(如配置参数、URL标记)在肉眼可见的情况下被轻易窥探,并提供基本的完整性校验。
- 性能考量:频繁调用
md5和字符串切片在数据量极大时会有轻微开销,但对于一般的Web请求响应而言影响可忽略不计。 - 兼容性:代码使用了
${var}形式的字符访问语法,这在PHP 7及更高版本中依然兼容,但在PHP 8中建议更严格的类型声明。
以上就是PHP动态加密解密函数实现的详细内容,更多关于PHP开发安全与数据保护的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









