迁移至Amazon Linux 2023后FPDF SetProtection异常要求密码
FPDF SetProtection 无密码PDF在Amazon Linux 2023要求输入密码的问题解决
问题背景
- 我们在AWS EC2实例上用FPDF多年,部分文档通过SetProtection脚本加密,仅开放打印权限
- 从Amazon Linux 2迁移到Amazon Linux 2023后,原本未设置密码的文档现在打开时要求输入密码
- 排查发现:脚本中调用
openssl_encrypt($data, 'RC4-40', $key, OPENSSL_RAW_DATA)在新环境返回空值,而脚本自带的纯PHP fallback加密逻辑能正常运行 - 环境参数对比:
- 正常环境:PHP 8.0.30、OpenSSL/1.0.2k-fips
- 异常环境:PHP 8.3.10、OpenSSL/3.0.8
问题根源
OpenSSL 3.0.x版本开始默认禁用了RC4-40这类弱加密算法,导致openssl_encrypt调用RC4-40时直接返回空值;而旧环境用的OpenSSL 1.0.2k-fips默认允许这类算法,所以之前能正常工作。
解决办法
办法1:强制使用纯PHP fallback加密
直接修改SetProtection脚本,跳过openssl的调用逻辑,始终用脚本里已有的纯PHP实现RC4加密:
// 先定义纯PHP版的RC4加密函数(用脚本里现成的fallback代码即可) function rc4_encrypt($data, $key) { $s = array(); for ($i = 0; $i < 256; $i++) { $s[$i] = $i; } $j = 0; $keyLen = strlen($key); for ($i = 0; $i < 256; $i++) { $j = ($j + $s[$i] + ord($key[$i % $keyLen])) % 256; $temp = $s[$i]; $s[$i] = $s[$j]; $s[$j] = $temp; } $i = $j = 0; $result = ''; $dataLen = strlen($data); for ($k = 0; $k < $dataLen; $k++) { $i = ($i + 1) % 256; $j = ($j + $s[$i]) % 256; $temp = $s[$i]; $s[$i] = $s[$j]; $s[$j] = $temp; $result .= chr(ord($data[$k]) ^ $s[($s[$i] + $s[$j]) % 256]); } return $result; } // 把原来的openssl_encrypt调用替换成上面的函数 // return openssl_encrypt($data, 'RC4-40', $key, OPENSSL_RAW_DATA); return rc4_encrypt($data, $key);
办法2:调整OpenSSL配置允许RC4-40(不推荐)
如果没法修改代码,只能调整OpenSSL配置来放行弱算法:
- 编辑OpenSSL配置文件
/etc/ssl/openssl.cnf,添加以下内容:
openssl_conf = default_conf [default_conf] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] CipherString = DEFAULT@SECLEVEL=0
- 重启PHP-FPM或Web服务器(比如
systemctl restart php-fpm)让配置生效
注意:降低安全级别会增加服务器的安全风险,仅在万不得已时使用
验证
修改后生成无密码的加密PDF,确认打开时不需要输入密码,且打印权限正常可用。
内容的提问来源于stack exchange,提问作者Dave Spencer
相关产品推荐
相关产品推荐

