我遇到了一个我无法理解的奇怪行为。
我正在使用 mcrypt xtea(cfb 模式)来加密一些数据。由于 php 7.2 正在摆脱 mcrypt 并且由于 openssl 也不支持 Xtea,因此我必须自己实现该算法。
问题是,无论使用什么算法:
我测试了这里提供的一个:pear implementation which is an ECB mode only (no init vector)
维基百科页面上提供的那个来自这个stackoverflow 主题
我在这里开发的一个(用于CFB模式)基于维基百科here 和here的以下两篇文章以及可以在here找到的mcrypt源代码 :
/* * $v is the data, $k is the 128bits key and $iv is 64bits init vector (size = 8) * Code is not optimized */ function encryptCfb($v, $k, $iv) { $v = array_values(unpack('N*', $v)); $iv = array_values(unpack('N*', $iv)); $k = array_values(unpack('N*', $k)); $cipher = []; //IV ciphering using the 128bits key list ($v0, $v1) = cipher($iv[0], $iv[1], $k); //Xoring the cipherd block with the first 64bits of data (32bits in V0 and 32 others in V1) $cipher[0] = $v0 ^ $v[0]; $cipher[1] = $v1 ^ $v[1]; for ($i=2; $i < count($v); $i+=2) { //Now ciphering the latest "cipherd" data using the 128bits key list ($y, $z) = cipher($cipher[$i-2], $cipher[$i-1], $k); //Xoring the cipherd block with the second 64bits of data (32bits in V0 and 32 others in V1) $cipher[$i] = $y ^ $v[$i]; $cipher[$i+1] = $z ^ $v[$i+1]; } $output = ""; foreach ($cipher as $i) { $output .= pack('N', $i); } return $output; } function cipher($v0, $v1, $k) { $delta=0x9e3779b9; $sum = 0; $limit = $delta * 32; for ($i=0; $i < 32; $i++) { $v0 += ((($v1<<4) ^ ($v1>>5)) + $v1) ^ ($sum + $k[$sum & 3]); $sum += $delta; $v1 += ((($v0 << 4) ^ ($v0 >> 5)) + $v0) ^ ($sum + $k[($sum>>11) & 3]); } return [$v0, $v1]; }
我得到了不同的结果,而且,它们都没有给出完全相同的结果 mcrypt 使用:
$cryptModule = mcrypt_module_open('xtea', '', 'ncfb', '');
mcrypt_generic_init($cryptModule, $key, $iv);
mcrypt_generic($cryptModule, $data);
您可以使用相同的 data/key/IV 检查和测试我在这里所做的不同测试:
-
- 轮数没有变化(32 或 64)
- 使用 N 模式(大端)或 V 模式(小端)打包/解包不会改变任何内容
有谁知道为什么我得到不同的结果?