在php中使用openssl对数据进行blowfish加密后,密文常含+、/、=等特殊字符,直接拼入url会导致+被$_get或$_request误作空格解析。正确做法是对密文执行urlencode()编码后再传参,并在接收端用urldecode()还原,而非更换加密算法。
当使用 openssl_encrypt()(如 Blowfish/CBC 模式)生成密文时,其默认输出为 Base64 编码格式(RFC 4648 §4),而 Base64 字符集包含 +、/ 和 = —— 这些字符在 URL 中具有特殊含义:+ 被传统表单编码(application/x-www-form-urlencoded)解释为空格,/ 可能干扰路径,= 常用于参数分隔。因此,问题根源并非加密算法本身,而是未对密文做 URL 安全转义。
✅ 正确处理流程如下:
-
加密后立即 URL 编码(发送端):
$passphrase = "testte@t"; $cipher = "bf-cbc"; // 推荐显式指定模式,如 bf-cbc(Blowfish-CBC) $id = "20220228-12";
// 注意:openssl_encrypt 需 IV(推荐随机生成并附带传输)
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$enc_str = openssl_encrypt($id, $cipher, $passphrase, OPENSSL_RAW_DATA, $iv);
// 将二进制密文 + IV 组合成可传输结构(如 base64(iv.enc)),再 URL 编码
$payload = base64_encode($iv . $enc_str);
$encoded_payload = urlencode($payload);
$url = “https://www.php.cn/link/ee373cca919c768548f9461eb171a6c7}”;
echo $url;
// 输出示例:https://www.php.cn/link/04ee08ead1a259009cab6b2198fb6d93 (含 %2B, %2F, %3D 等)
2. **接收端先 URL 解码,再 Base64 解码与解密**(服务端):
```php
$encoded_payload = $_GET['p'] ?? '';
$payload = urldecode($encoded_payload); // 还原原始 base64 字符串
$data = base64_decode($payload);
if ($data === false) {
die('Invalid payload');
}
$ivlen = openssl_cipher_iv_length('bf-cbc');
$iv = substr($data, 0, $ivlen);
$enc_data = substr($data, $ivlen);
$decrypted = openssl_decrypt($enc_data, 'bf-cbc', $passphrase, OPENSSL_RAW_DATA, $iv);
if ($decrypted === false) {
die('Decryption failed: ' . openssl_error_string());
}
echo "Decrypted ID: " . $decrypted; // → "20220228-12"
⚠️ 关键注意事项: