【问题标题】:Cryptography libraries conflict (MCrypt, libgcrypt)密码库冲突(MCrypt、libgcrypt)
【发布时间】:2011-03-10 02:22:57
【问题描述】:

我正在尝试在两个不同的组件中执行加密和解密(Rijndael 256,ecb 模式):
1. PHP - 服务器端(使用 mcrypt)
2. C++ - 客户端(使用 gcrypt)

当客户端无法正确解密加密数据(由服务器端生成)时,我遇到了问题
所以...我检查了:
1.初始向量 - 相同相同(32长度)
2. 钥匙 - 两边同样的钥匙..

所以我用 C++ 编写了一些代码来加密数据(使用与 php 中相同的参数)
我发现加密数据包含不同的字节(可能是编码问题??)

我会很高兴得到一些帮助

PHP - MCrypt


// Encrypt Function
function mc_encrypt($encrypt, $mc_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $iv = "static_init_vector_static_init_v";
    echo "IV-Size: " . $iv_size . "\n";
    echo "IV: " . $iv . "\n";
    $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, $encrypt, MCRYPT_MODE_ECB, $iv);
    print_hex($passcrypt);
    return $encode;
}

mc_encrypt("Some text which should be encrypted...","keykeykeykeykeykeykeykeykeykeyke");

我会在评论中发布 C++ 代码

谢谢, 约翰尼德普

【问题讨论】:

  • C++ - libgcrypt(我将 C++ 文件上传到 hotfile)hotfile.com/dl/51575328/ce8af3a/gcrypt.cpp.html 再次感谢..
  • 您可能应该查找一些 AES 测试向量并通过这两种实现来运行它们以找出哪一个出错了。我希望这些实现必须有效,所以你可能使用了一个稍微错误的方法。
  • 在 ECB 模式下不使用初始化向量 (IV)。如果提供了不同的实现,则可能会有所不同。如果您想确保实现能够正常工作,请使用 0(零)的 IV。尽管您提供了 IV,但两种实现都应该忽略它,但永远无法确定这一点。在 ECB 模式下不提供 IV 应该也可以,但同样,这完全取决于实现。

标签: php c++ mcrypt


【解决方案1】:

好的。我会让我的评论成为答案:

在 ECB 模式下不使用初始化向量 (IV)。如果提供它,不同的实现可能会有不同的工作方式。

如果您想确保实现能够正常工作,请使用 0(零)的 IV。即使您提供了 IV,两种实现都应该忽略它,但人们永远无法确定这一点。在 ECB 模式下不提供 IV 应该也可以,但同样,这完全取决于实现。

根据 PHP documentation MCrypt 将忽略它。 GCrypt 我不确定。

mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB) 实际上应该返回 0,因为您指定了 ECB 模式。

编辑:

请勿致电mcrypt_get_iv_sizemcrypt_create_iv
而是在没有 IV 的情况下调用 mcrypt_encrypt。根据 PHP documentation,IV 中的所有字节都将设置为 '\0'。

C++ 代码也是如此。根本不需要设置任何 IV。 libgcrypt 代码很复杂,但从 1.4.5 版本的源代码看,在 ECB 模式下似乎根本没有使用 IV。

如果生成的密文仍然不同,则问题出在其他问题上。
我想到了几种可能性:

  • 编码 - 服务器和客户端是否使用相同的编码?
  • 字节顺序 - 服务器和客户端是什么类型的系统?大端 vs 小端?

【讨论】:

  • 嗨 Sani,函数 mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB) 在我的环境中返回 32。我在哪里可以强制忽略 IV?
  • 我将 IV 的值更改为零,我得到相同的结果(不同的值)
  • 关于 Endianness 目前它是同一台机器(32 位 ubuntu)所以我猜这还不是我的问题。 (顺便说一句)以及关于 PHP 中 C++ 中的编码 utf8(使用 char*)我通过 if(is_utf8($encrypt) == false) { $encrypt = utf8_encode($encrypt); 强制 utf8 编码} if(is_utf8($mc_key) == false) { $mc_key = utf8_encode($mc_key); } $passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, $encrypt, MCRYPT_MODE_ECB, $iv); if(is_utf8($passcrypt) == false) { $passcrypt = utf8_encode($passcrypt); }
  • 你确定你在 C++ 中使用 UTF8 吗?在我看来,您使用的是纯 ASCII。 string.c_str() 不会将文本转换为 UTF8。
  • 不确定,我通过在 php 中打印“Hello”的字节(首先调用 mb_internal_encoding("UTF-8"))、C++(使用 g++)、C++(使用 Visual Studio)所有测试人员都返回“\x48\x65\x6c\x6c\x6f”,出于某种原因,当我尝试加密时,我仍然得到不同的值:\
猜你喜欢
  • 1970-01-01
  • 2013-01-11
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多