PHP7加密文件解密需先启用OpenSSL扩展,再用openssl_decrypt配合匹配的密钥、IV及算法参数;若失败,检查密钥/IV长度、填充方式,并用openssl_error_string定位错误。
如果您拥有一个使用PHP7环境加密生成的文件,但当前解密失败或结果异常,则很可能是由于加密所用扩展、算法参数或PHP版本兼容性不匹配所致。以下是针对PHP7加密文件进行解密的具体操作路径:
一、确认加密所用扩展并启用对应解密模块
PHP7默认禁用mcrypt扩展,且仅支持OpenSSL作为主流加解密接口;若加密时使用了openssl_encrypt(),则解密必须使用openssl_decrypt(),且需确保
php
.ini中已启用openssl扩展。
1、在命令行执行
,确认openssl模块已加载。
2、打开php.ini文件,检查是否存在
且未被注释;若无,手动添加该行。
立即学习
“
PHP免费学习笔记(深入)
”;
3、重启Web服务器(如Apache)或PHP-FPM服务,使配置生效。
4、创建验证脚本
,内容为
,浏览器访问或CLI执行确认输出为
OpenSSL可用
。
二、使用openssl_decrypt还原AES/CBC等标准加密数据
该方法适用于PHP7中通过
以AES-128-CBC、AES-256-CBC等模式加密的Base64编码字符串,要求密钥(key)、初始化向量(iv)、密码算法、选项参数与加密时完全一致。
1、将加密后的Base64字符串赋值给变量
,例如
。
2、使用
将其还原为原始密文二进制数据。
3、定义与加密时相同的32字节密钥(AES-256)或16字节密钥(AES-128),以及16字节IV(CBC模式必需)。
4、调用
,注意若加密时使用
,此处无需再次base64_decode,但若加密输出为Base64,则必须先解码。
5、对解密结果使用
或
去除填充字节,其中
需自行定义函数处理PKCS#7填充。
三、兼容PHP5遗留加密参数的降级适配方案
部分PHP7加密脚本为向前兼容PHP5而采用与mcrypt行为一致的填充和截断逻辑,此时需手动模拟mcrypt的PKCS#5填充规则,并调整openssl_decrypt的选项以规避自动填充处理。
1、若加密时使用
且未显式填充,则解密前需确保原始数据长度为块大小(16字节)整数倍,否则需补零或PKCS#7填充后再解密。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
2、构造解密参数:$cipher = 'AES-128-CBC',$options = OPENSSL_ZERO_PADDING(禁用自动填充),$key与$iv严格保持十六进制原始字节或二进制格式,
禁止将密钥或IV进行base64_encode或hex2bin误转换
。
3、执行解密后,若结果末尾出现乱码或空字符,说明填充方式不匹配,应改用
或自定义PKCS#7去填充函数。
4、编写辅助函数
,并在解密后立即调用。
四、解密Base64或URL安全Base64编码的非加密内容
某些“加密”实为单纯编码混淆,如前端JavaScript使用btoa()或PHP使用base64_encode()封装文本、JSON或二进制资源,此类情况无需密码或算法,仅需逆向解码即可还原原始内容。
1、读取目标文件内容:
。
2、判断是否为URL安全Base64(含
和
字符):若存在,需替换为标准Base64字符
和
,并补足
至长度为4的倍数。
3、调用
获取原始字节流。
4、检测
是否为UTF-8文本:
,若是,直接
;若否,尝试
判断是否为图片,或写入临时文件用十六进制工具查看头部魔数。
5、若解码后内容仍不可读,说明其实际为二次加密(如AES密文再经Base64编码),此时应回到第二或第三方案继续处理。
五、调试密钥与IV长度不匹配导致的静默失败
openssl_decrypt在密钥或IV长度不符合算法要求时可能返回false而不报错,尤其当密钥被错误地以字符串字面量传入(如
)却未补足至32字节,或IV未严格16字节(AES-CBC),将导致解密失败但无明确提示。
1、校验密钥长度:
(AES-256)或
(AES-128),若不足,使用
生成固定长度二进制密钥。
2、校验IV长度:
,若来源为hex字符串,必须先用
转换;若为Base64,须
后再测长。
3、在解密前插入诊断代码:
,确认三者匹配。
4、若
返回false,立即调用
捕获底层OpenSSL错误信息,常见提示如
"IV length not valid for this cipher"
或
"Key length not valid for this cipher"
可直接定位问题。
php -m | grep opensslextension=opensslcheck_openssl.phpopenssl_encrypt()$encrypted$encrypted = 'U2FsdGVkX1+...';base64_decode()openssl_decrypt($data, 'AES-256-CBC', $key, OPENSSL_ZERO_PADDING, $iv)OPENSSL_RAW_DATAtrim($result, "\0")pkcs7_unpad($result)pkcs7_unpadopenssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv)OPENSSL_PKCS1_PADDINGfunction pkcs7_unpad($data) { $pad = ord($data[strlen($data)-1]); return substr($data, 0, -$pad); }$encoded = file_get_contents('encrypted.txt');-_+/=$raw = base64_decode($encoded);$rawmb_check_encoding($raw, 'UTF-8')echo $rawgetimagesizefromstring($raw)'mykey123'strlen($key) === 32=== 16hash('sha256', $key, true)strlen($iv) === 16hex2bin($iv)base64_decode($iv)var_dump(['key_len'=>strlen($key),'iv_len'=>strlen($iv),'cipher'=>'AES-256-CBC']);openssl_decrypt()openssl_error_string()