开发者社区 问答 正文

php7.1openssl_encrypt加密问题:报错

谁知道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;

 

展开
收起
kun坤 2020-06-14 14:00:36 781 分享 版权
阿里云 AI 助理回答

openssl_encryptmcrypt_encrypt 是 PHP 中用于加密的两个不同函数,它们在实现细节上有所差异。由于 mcrypt 扩展已被废弃并在 PHP 7.1 版本后移除,推荐使用 openssl_encrypt 进行加密操作以确保兼容性和安全性。

要使两者之间兼容,你需要确保加密方式、填充模式、密钥(Key)、初始化向量(IV)等参数设置一致。对于你提到的场景,AES-128-CBC 加密且需要零填充(zeropadding),可以尝试以下方法调整以达到兼容目的:

使用 openssl_encrypt

首先,确认你的代码已经使用了 openssl_encrypt,这是推荐的做法。你已正确设置了 AES-128-CBC 模式和提供了密钥及 IV。但需要注意的是,OPENSSL_RAW_DATA 标志表示输出原始二进制数据,这与 mcrypt 的默认行为一致。对于零填充,PHP 的 openssl_encrypt 实际上并不直接支持指定填充类型,它默认使用 PKCS7 填充,而 mcrypt 默认可能不进行任何填充或使用其他策略,这可能是导致两者结果不一致的原因之一。

如果你确实需要零填充(虽然这不是一个安全的标准做法),你可能需要在加密前后手动添加或移除填充。但是,请注意,直接使用零填充可能会导致解密问题,特别是当明文长度恰好是块大小的整数倍时。

转换为类似 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 并遵循其推荐的配置是最理想的解决方案。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答