需逐层逆向还原多层加密:先识别算法组合与顺序,再按反序解密(如base64→aes→hmac绕过),严格匹配各层密钥、iv及参数;遇自定义混淆需先还原;调试时记录中间态验证。

如果php脚本对数据执行了多层加密操作,导致原始内容无法直接读取,则需根据实际使用的加密算法、密钥、向量及嵌套顺序逐层逆向还原。以下是针对常见多层加密场景的解密操作步骤:
一、确认加密层级与算法组合
多层加密通常由多个独立加密函数嵌套构成,例如base64_encode()包裹openssl_encrypt()再包裹urlencode()。必须先识别每层所用函数、参数(如cipher、mode、padding、IV)及执行顺序,否则解密将失败。
1、检查PHP源码中加密调用链,从最外层开始向内逐级记录函数名与参数。
2、若无源码,尝试对密文进行常见编码特征分析:base64字符串长度为4的倍数且含A-Za-z0-9+/=字符;十六进制字符串仅含0-9a-f且长度为偶数;URL编码密文包含%开头的双字符序列。
立即学习“PHP免费学习笔记(深入)”;
3、使用在线工具或PHP内置函数进行试探性解码,例如先urldecode(),再hex2bin(),最后base64_decode(),观察是否产生可识别的二进制头部(如PK..表示ZIP)或明文片段。
二、逐层逆向解密:Base64 → AES → HMAC校验绕过
当密文结构为base64( openssl_encrypt( $data, ‘AES-256-CBC’, $key, 0, $iv ) ),且附带HMAC签名时,需先剥离签名,再按相反顺序解密。
1、将完整密文按约定分隔符(如冒号、点号)拆分为数据段与签名段,例如 explode(‘.’, $cipherText)。
2、对数据段执行base64_decode(),获取原始加密字节流。
3、提取前16字节作为IV,剩余部分为密文主体,调用openssl_decrypt()并传入相同$key与’AES-256-CBC’参数。
4、若HMAC校验失败但确定密钥正确,可临时注释或跳过hash_hmac()验证逻辑,直接进入解密流程。
三、处理多次openssl_encrypt嵌套
若存在openssl_encrypt(openssl_encrypt($data, $cipher1, $key1), $cipher2, $key2),则必须严格按反序调用对应解密函数,且各层密钥、IV、填充方式必须完全一致。
1、使用openssl_decrypt()解最外层,参数$cipher2、$key2、$iv2需与加密时完全相同。
2、将上一步输出结果再次传入openssl_decrypt(),使用$cipher1、$key1、$iv1进行第二层解密。
3、检查每层解密后输出的长度与PKCS#7填充特征,若出现乱码但长度规整(如64字节倍数),说明某层IV或密钥错误。
四、应对自定义混淆层(如字符替换、位移、反转)
部分实现会在加密前后加入非标准混淆,例如strrev()、str_rot13()或逐字节异或固定值,此类操作不依赖密钥,但必须还原才能继续标准解密。
1、对base64解码后的二进制数据,尝试执行strrev(),观察是否出现可识别的json或xml头部。
2、对疑似ROT13处理的数据,再次调用str_rot13()还原。
3、若存在固定异或掩码(如$data[i] ^ 0x5A),遍历密文前16字节与常见ASCII标点异或,发现连续可读字符即表明异或值正确。
五、调试模式下提取中间态密文
当无法准确判断加密顺序时,可在原加密代码中插入临时日志,记录每一层输出,从而构建完整的加解密映射关系。
1、在每层加密函数调用后添加file_put_contents(‘/tmp/layer1.bin’, $output, FILE_APPEND)。
2、使用hexdump -C /tmp/layer1.bin查看十六进制结构,比对各层输入输出长度变化。
3、将各层中间文件按逆序载入PHP,依次执行对应解密函数,确保每步输出与前一层输入完全一致。