如何在PHP 7.4中解密MCRYPT_BLOWFISH+ECB加密内容
PHP 7.4兼容的Blowfish-ECB解密方案(替代mcrypt)
核心解密函数(兼容原有加密内容)
直接替换原decrypt函数,完全匹配PHP 5.6中mcrypt_decrypt的行为:
function decrypt($encrypted_string, $encryption_key) { // 对应原MCRYPT_BLOWFISH + MCRYPT_MODE_ECB $decrypted = openssl_decrypt( $encrypted_string, 'BF-ECB', $encryption_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING ); // 移除原mcrypt自动添加的零填充字符,与原代码trim逻辑一致 return rtrim($decrypted, "\0"); }
配套加密函数(用于生成新的URL参数)
如果需要生成新的加密参数,替换原encrypt函数,保证和旧加密逻辑一致:
function encrypt($string, $encryption_key) { $string_utf8 = utf8_encode($string); // Blowfish块大小为8字节,手动添加零填充(匹配mcrypt自动填充行为) $block_size = 8; $padding_len = $block_size - (strlen($string_utf8) % $block_size); $padded_string = $string_utf8 . str_repeat("\0", $padding_len); return openssl_encrypt( $padded_string, 'BF-ECB', $encryption_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING ); }
原有调用代码无需修改
生成URL查询参数的代码保持不变:
define("ENCRYPTION_KEY", "_enc_key"); $example_string = "My_String|2|Encode"; $enc_url_param = urlencode(base64_encode(encrypt($example_string, ENCRYPTION_KEY)));
解密查询参数的代码仅需替换decrypt函数,trim可以保留(或直接用rtrim($decrypted, "\0"),效果一致):
$decrypted = trim(decrypt(base64_decode($_GET['enc_param']), ENCRYPTION_KEY));
关键匹配点说明
- 算法与模式:原
MCRYPT_BLOWFISH对应OpenSSL的BF-ECB算法标识,ECB模式完全一致 - 填充规则:mcrypt默认使用零填充(不足块大小的部分用
\0填充),OpenSSL默认用PKCS7填充,因此必须指定OPENSSL_ZERO_PADDING才能匹配旧加密内容的格式 - 数据格式:
OPENSSL_RAW_DATA确保输入输出为原始字节流,与原mcrypt_encrypt/decrypt的行为一致,避免自动base64编解码 - 密钥一致性:必须保证
ENCRYPTION_KEY与原PHP 5.6环境完全相同,Blowfish密钥长度范围为4-56字节,mcrypt会直接使用给定密钥(超出长度会截断)
注意事项
- ECB模式加密强度较低,但根据你的场景(仅用于混淆URL中的ID,已有其他安全措施),可以继续使用
- 测试时建议拿一个已知的旧加密参数验证,确保解密结果与原代码一致
内容的提问来源于stack exchange,提问作者matteo
相关产品推荐
相关产品推荐

