PHP7.4环境下替换mcrypt实现Sagepay/Opayo加解密函数
替换mcrypt实现Sagepay/Opayo的Crypt字段加密解密
加密函数替换(替代encryptAndEncode)
使用PHP内置的openssl扩展替代已废弃的mcrypt,完全匹配原逻辑的AES-128 CBC模式、PKCS#5填充、密钥/IV复用加密密码的要求:
protected function encryptAndEncode($strIn) { $strIn = $this->pkcs5_pad($strIn, 16); // AES-128要求密钥/IV为16字节,与原mcrypt行为一致,截断密码到16字节 $key = substr($this->encryptPassword, 0, 16); $iv = $key; // 复用密钥作为初始化向量 // 加密并返回原始二进制数据 $encrypted = openssl_encrypt($strIn, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); // 转大写十六进制并添加@前缀,符合Sagepay格式要求 return '@' . strtoupper(bin2hex($encrypted)); }
解密函数替换(替代decodeAndDecrypt)
反向实现加密逻辑,保持与原函数的输出行为一致:
protected function decodeAndDecrypt($strIn) { $strIn = substr($strIn, 1); // 移除@前缀 $binaryData = pack('H*', $strIn); // 十六进制转二进制 $key = substr($this->encryptPassword, 0, 16); $iv = $key; // 解密并返回原始明文(包含PKCS#5填充,需自行调用去填充函数处理) return openssl_decrypt($binaryData, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); }
辅助:PKCS#5填充/去填充函数
如果你的类中还没有实现PKCS#5的填充逻辑,可添加以下函数:
protected function pkcs5_pad($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } // 解密后调用此函数移除填充 protected function pkcs5_unpad($text) { $pad = ord($text[strlen($text)-1]); if ($pad > strlen($text) || strspn($text, chr($pad), strlen($text) - $pad) != $pad) { return false; } return substr($text, 0, -1 * $pad); }
关键说明
openssl是PHP7.4+默认启用的扩展,无需额外安装配置- 严格匹配原逻辑:密钥和IV均复用加密密码并截断为16字节(AES-128要求)
- 加密结果转大写十六进制,完全符合Sagepay的Crypt字段格式规范
- 解密后返回的明文包含PKCS#5填充,需自行调用
pkcs5_unpad处理(与原函数行为一致)
内容的提问来源于stack exchange,提问作者scim1971
相关产品推荐
相关产品推荐

