使用PHP OpenSSL加密输出含特殊字符解密失败该如何处理?
问题原因
openssl_encrypt在不传入OPENSSL_RAW_DATA参数的情况下,默认返回的加密结果就是Base64编码格式,天然包含+、/、=三个特殊字符。你没有对$simple_string做Base64编码不会导致解密异常,问题的根源是加密后的输出串在存储、传输过程中经过了URL转义、特殊字符过滤等处理,原始结构被破坏,导致解密时拿到的不是加密函数输出的原始值。
已有带特殊字符加密串的解密步骤
- 先将待解密串还原为
openssl_encrypt输出的原始值:- 若加密串经过URL传输:调用
urldecode()处理待解密串,将被转义的+(URL编码后为%2B)、/(URL编码后为%2F)还原 - 若加密串经过自定义特殊字符过滤:按照过滤规则逆向还原,确保待解密串和加密生成的原始串完全一致
- 若加密串经过URL传输:调用
- 直接调用
openssl_decrypt处理还原后的加密串即可:
// 示例为URL转义场景的解密代码 $raw_encryption = urldecode($received_encryption); $decrypted_string = openssl_decrypt($raw_encryption, $ciphering, $encryption_key, $options, $encryption_iv);
后续加密的优化方案
要从根源避免特殊字符导致的异常,可以对加密后的串做URL安全的Base64转码处理:
// 加密阶段:生成URL安全的加密串 $original_encryption = openssl_encrypt($simple_string, $ciphering, $encryption_key, $options, $encryption_iv); $safe_encryption = str_replace(['+', '/', '='], ['-', '_', ''], $original_encryption); // 解密阶段:先还原为标准Base64格式再解密 $restore_encryption = str_replace(['-', '_'], ['+', '/'], $safe_encryption); // 补全Base64必要填充位 $restore_encryption .= str_pad('', (4 - strlen($restore_encryption) % 4) % 4, '='); $decrypted_string = openssl_decrypt($restore_encryption, $ciphering, $encryption_key, $options, $encryption_iv);
内容的提问来源于stack exchange,提问作者Daniel987
相关产品推荐
相关产品推荐

