PHP8实现AES-128-CBC模式PKCS#5填充对接Sage Pay/Opayo问题
PHP8对接Sage Pay(Opayo)AES加密解决方案
PHP内置openssl扩展默认启用PKCS#7自动填充,要实现需求中的PKCS#5填充只需关闭openssl自动填充,手动实现填充逻辑后再加密即可。
1. 自定义PKCS#5填充/解填充函数
/** * PKCS#5填充 * @param string $text 待填充原始字符串 * @param int $blocksize 块大小,AES固定为16 * @return string 填充后字符串 */ function pkcs5_pad(string $text, int $blocksize = 16): string { $padLength = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($padLength), $padLength); } /** * PKCS#5解填充 * @param string $text 解密后待去填充字符串 * @return string 原始字符串 */ function pkcs5_unpad(string $text): string { $padLength = ord($text[strlen($text) - 1]); if ($padLength > strlen($text) || strspn($text, chr($padLength), strlen($text) - $padLength) !== $padLength) { return $text; } return substr($text, 0, -$padLength); }
2. 改写加密逻辑
$cryptFieldString = http_build_query($cryptFields); // 手动完成PKCS#5填充 $paddedContent = pkcs5_pad($cryptFieldString); // 关闭openssl自动填充,返回原始二进制加密结果 $encodedCrypt = openssl_encrypt($paddedContent, 'aes-128-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $key); // 按Sage Pay要求格式化输出 $crypt = '@' . strtoupper(bin2hex($encodedCrypt));
注意事项
- AES-128要求密钥长度必须为16字节,需确认你使用的
$key长度符合要求,过长会被openssl截断、过短会自动补0,都会导致加密结果不被Sage Pay认可 - 你当前使用密钥作为IV值的逻辑需确认和Sage Pay对接规范一致,若规范要求随机IV需对应调整逻辑
- 解密Sage Pay返回的加密数据时,需先调用openssl_decrypt后再执行pkcs5_unpad去掉填充即可拿到原始数据
内容的提问来源于stack exchange,提问作者Celf Creative
相关产品推荐
相关产品推荐

