理解できない奇妙な行動に出くわしました。
一部のデータを暗号化するために mcrypt xtea (cfb モード) を使用しています。PHP 7.2 では mcrypt が取り除かれ、openssl は Xtea をサポートしていないため、アルゴリズムを自分で実装する必要がありました。
問題は、使用されるアルゴリズムに関係なく、次のとおりです。
ここで提供されているものをテストしました: ECB モードのみのpear 実装(初期化ベクトルなし)
そして、このstackoverflowトピックから取られたウィキペディアのページで提供されているもの
そして、私がここで(CFBモード用に)開発したものは、ウィキペディアのここ とここの2つの次の記事と、ここにある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);
同じデータ/キー/IV を使用して、ここで行ったさまざまなテストを確認してテストできます。
CFB モードでの私の実装 VS mcrypt。ご了承ください :
- ラウンド数は何も変わりません (32 または 64)
- N モード (ビッグ エンディアン) または V モード (リトルエンディアン) を使用したパック/アンパックは何も変更しません
異なる結果が得られる理由を誰かが知っていますか?