mcrypt_encrypt 到 openssl_encrypt 和 OPENSSL_ZERO_PADDING 问题 [英] mcrypt_encrypt to openssl_encrypt, and OPENSSL_ZERO_PADDING problems

查看:137
本文介绍了mcrypt_encrypt 到 openssl_encrypt 和 OPENSSL_ZERO_PADDING 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于给定的 $key$message$iv,我有这个 mcrypt_encrypt 调用:

I have this mcrypt_encrypt call, for a given $key, $message and $iv:

$string = mcrypt_encrypt(MCRYPT_3DES, $key, $message, MCRYPT_MODE_CBC, $iv);

我想将 mcrypt_encrypt 调用更改为 openssl_encrypt 调用,以防止将来发生这种情况.

I'd like to change the mcrypt_encrypt call to an openssl_encrypt one, to future-proof this.

通过让 $mode = 'des-ede3-cbc'$mode = '3DES';$options = true 我得到更相似的响应,但不完全相同.有没有其他方法可以调用它以获得完美匹配?

By having $mode = 'des-ede3-cbc' or $mode = '3DES'; and $options = true I get the more similar response, but not identical. Is there other way to call it to get a perfect match?

我得到了一个 lorem-ipsum $message+$key 组合的这个(base64_encoded),所以我开始相信一个或另一个函数是在加密之前稍微填充消息...

I'm getting this (base64_encoded) for a lorem-ipsum $message+$key combinations, so I'm starting to believe one function or the other are padding somewhat the message before encrypting...

对于 mcrypt

"Y+JgMBdfI7ZYY3M9lJXCtb5Vgu+rWvLBfjug2GLX7uo="

"Y+JgMBdfI7ZYY3M9lJXCtb5Vgu+rWvLBfjug2GLX7uo="

对于openssl

"Y+JgMBdfI7ZYY3M9lJXCtb5Vgu+rWvLBvte4swdttHY="

"Y+JgMBdfI7ZYY3M9lJXCtb5Vgu+rWvLBvte4swdttHY="

尝试使用 $options 来传递 OPENSSL_ZERO_PADDING,但除了 1(OPENSSL_RAW_DATAtrue)结果是一个空字符串...

Tried using $options to pass OPENSSL_ZERO_PADDING, but passing anything but 1 (OPENSSL_RAW_DATA, or true) results in an empty string...

既不使用OPENSSL_ZERO_PADDING 也不使用OPENSSL_RAW_DATA |OPENSSL_ZERO_PADDING 工作... :(我使用的是OpenSSL 1.0.2g 2016 年 3 月 1 日".

Neither using OPENSSL_ZERO_PADDING nor OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING work... :( I'm using "OpenSSL 1.0.2g 1 Mar 2016".

已经阅读了这个问答,但它没有'帮我.不是one 有填充问题,但没有到目前为止的解决方案.(第二个答案是关于向 mcrypt 调用添加填充,我真的很想从 openssl 加密调用中删除填充...

Already read this q&a, but it doesn't help me. Not the only one with padding troubles, but no solution in sight so far. (Second answer talks about adding padding to mcrypt call, I would really want to remove padding from openssl encryption call...

推荐答案

mcrypt_encrypt 零填充输入数据,如果它不是块大小的倍数.如果数据本身有尾随零,这会导致不明确的结果.显然 OpenSSL 不允许您在这种情况下使用零填充,这解释了错误的返回值.

mcrypt_encrypt zero-pads input data if it's not a multiple of the blocksize. This leads to ambiguous results if the data itself has trailing zeroes. Apparently OpenSSL doesn't allow you to use zero padding in this case, which explains the false return value.

您可以通过手动添加填充来规避此问题.

You can circumvent this by adding the padding manually.

$message = "Lorem ipsum";
$key = "123456789012345678901234";
$iv = "12345678";

$message_padded = $message;
if (strlen($message_padded) % 8) {
    $message_padded = str_pad($message_padded,
        strlen($message_padded) + 8 - strlen($message_padded) % 8, "\0");
}
$encrypted_mcrypt = mcrypt_encrypt(MCRYPT_3DES, $key,
    $message, MCRYPT_MODE_CBC, $iv);
$encrypted_openssl = openssl_encrypt($message_padded, "DES-EDE3-CBC", 
    $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);

printf("%s => %s\n", bin2hex($message), bin2hex($encrypted_mcrypt));
printf("%s => %s\n", bin2hex($message_padded), bin2hex($encrypted_openssl));

这将打印出相等的内容.

This prints both as equal.

4c6f72656d20697073756d => c6fed0af15d494e485af3597ad628cec
4c6f72656d20697073756d0000000000 => c6fed0af15d494e485af3597ad628cec

这篇关于mcrypt_encrypt 到 openssl_encrypt 和 OPENSSL_ZERO_PADDING 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆