谁知道openssl_encrypt和mcrypt_encrypt加密方式不一样怎么兼容么?
采用AES-128-CBC,需要填充方式zeropadding
$privateKey = $iv = '3B65571F4EB0F92E';
$data = '{"ordernumber":"1511950693"}';
$encrypted = openssl_encrypt($data, "AES-128-CBC", $privateKey, OPENSSL_RAW_DATA, $iv);
var_dump($encrypted);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv);
var_dump($encrypted);exit;
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
openssl_encrypt
和 mcrypt_encrypt
是 PHP 中用于加密的两个不同函数,它们在实现细节上有所差异。由于 mcrypt
扩展已被废弃并在 PHP 7.1 版本后移除,推荐使用 openssl_encrypt
进行加密操作以确保兼容性和安全性。
要使两者之间兼容,你需要确保加密方式、填充模式、密钥(Key)、初始化向量(IV)等参数设置一致。对于你提到的场景,AES-128-CBC 加密且需要零填充(zeropadding),可以尝试以下方法调整以达到兼容目的:
首先,确认你的代码已经使用了 openssl_encrypt
,这是推荐的做法。你已正确设置了 AES-128-CBC 模式和提供了密钥及 IV。但需要注意的是,OPENSSL_RAW_DATA
标志表示输出原始二进制数据,这与 mcrypt 的默认行为一致。对于零填充,PHP 的 openssl_encrypt
实际上并不直接支持指定填充类型,它默认使用 PKCS7 填充,而 mcrypt 默认可能不进行任何填充或使用其他策略,这可能是导致两者结果不一致的原因之一。
如果你确实需要零填充(虽然这不是一个安全的标准做法),你可能需要在加密前后手动添加或移除填充。但是,请注意,直接使用零填充可能会导致解密问题,特别是当明文长度恰好是块大小的整数倍时。
若要模拟 mcrypt 的某些特定行为(如特定的填充方式),你可能需要编写额外的逻辑来处理填充。然而,强烈建议遵循安全标准,使用 PKCS7 填充,并保持使用 openssl_encrypt
。
如果你坚持要模拟零填充,这里有一个简化的示例,但请注意,这种方法可能不适用于所有情况,尤其是涉及到安全性要求较高的场景:
$privateKey = $iv = '3B65571F4EB0F92E';
$data = '{"ordernumber":"1511950693"}';
// 对于 openssl_encrypt,我们通常不需要手动处理零填充,因为填充是由算法控制的。
// 但为了模拟 mcrypt 的可能行为,我们可以尝试手动零填充到块大小的倍数。
$blockSize = 16; // AES-128 的块大小
$dataPadded = str_pad($data, ceil(strlen($data) / $blockSize) * $blockSize, "\0");
$encrypted = openssl_encrypt($dataPadded, "AES-128-CBC", $privateKey, OPENSSL_RAW_DATA, $iv);
var_dump(bin2hex($encrypted)); // 使用 bin2hex 可以更方便地查看二进制数据
// 注意:此处未提供 mcrypt_encrypt 的替代方案,因为它已被废弃,应避免使用。
请记住,上述示例仅作为理解不同加密方式间差异的参考,实际应用中应优先考虑安全性和标准化实践。如果可能,完全迁移到 openssl_encrypt
并遵循其推荐的配置是最理想的解决方案。