Я столкнулся со странным поведением, которое я не мог понять.
Я использую mcrypt xtea (режим cfb) для шифрования некоторых данных.
Поскольку php 7.2 избавляется от mcrypt и так как openssl не поддерживает и не поддерживает Xtea, мне пришлось самому реализовать алгоритм.
Проблема в том, какой бы алгоритм не использовался:
Я проверил один из приведенных здесь: реализация груши только режим ECB (без начального вектора)
И тот, который предоставлен на странице википедии, взят из этого тема stackoverflow
И тот, который я разработал здесь (для режима CFB), основываясь на двух следующих статьях из Википедии Вот а также Вот и исходный код 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:
Моя реализация VS Mcrypt в режиме CFB. Обратите внимание, что :
Кто-нибудь знает, почему я получаю другой результат?
Он должен работать с модулями на $ v0 и $ v1:
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]);
$v0 = $v0 % pow(2, 32);
$sum += $delta;
$v1 += ((($v0 << 4) ^ ($v0 >> 5)) + $v0) ^ ($sum + $k[($sum>>11) & 3]);
$v1 = $v1 % pow(2, 32);
}
return [$v0, $v1];
}
Вам также необходимо изменить размер входного значения $v
чтобы убедиться, что он имеет правильную длину, например, с _resize(&$data, $size, $nonull = false)
функция модуля PEAR Crypt_Xtea
Вы упоминаете.
Других решений пока нет …