我遇到了一种我无法理解的奇怪的行为。
我使用mcrypt (cfb模式)加密一些数据。由于php 7.2正在摆脱mcrypt,而且由于openssl不支持Xtea,所以我不得不自己实现该算法。
问题是,无论使用的算法是:
我得到了一个不同的结果,而且,没有一个结果与mcrypt给出的结果完全相同:
$cryptModule = mcrypt_module_open('xtea', '', 'ncfb', '');
mcrypt_generic_init($cryptModule, $key, $iv);
mcrypt_generic($cryptModule, $data);您可以使用相同的数据/key/IV检查和测试我在这里进行的不同测试:
- The number of rounds changes nothing (32 or 64)
- Packing/Unpacking using N mode (big endian) or V mode (little endian) changes nothings
有人知道我为什么会得到不同的结果吗?
发布于 2019-02-25 21:45:58
有人知道我为什么会得到不同的结果吗?
我没有,但我怀疑所有的老人(2006年及以上?)userland实现从来没有测试过,在64位PHP上也不起作用。
我只需要在一个项目中使用XTEA,和您一样,我测试了所有其他可用的XTEA实现,它们都是very old,而且没有一个得到正确的结果(我怀疑所有2006年和更旧的实现都没有在64位系统上进行测试,它们也不能在64位系统上工作)
长话短说,我用PHP从头开始编写了一个64位兼容的XTEA实现,代码可以在这里找到:https://github.com/divinity76/php-xtea。
示例
<?php
require_once('XTEA.class.php');
$key_binary = "secret";
$keys_array = XTEA::binary_key_to_int_array($key_binary);
$data = "Hello, World!";
$encrypted = XTEA::encrypt($data, $keys_array);
$decrypted = XTEA::decrypt($encrypted, $keys_array);
var_dump($data, $encrypted, $decrypted);应该输出如下这样的内容:
string(13) "Hello, World!"
string(16) "□□Jx□□□□□□□ܴ9"
string(16) "Hello, World! "长度是不同的,因为x茶长度填充,可以通过以下方式禁用
XTEA::encrypt($data, $keys_array, XTEA::PAD_NONE);这会给你:
PHP Fatal error: Uncaught InvalidArgumentException: with PAD_NONE the data MUST be a multiple of 8 bytes! in /cygdrive/c/projects/tibia_login_php/xtea.class.php:73
Stack trace:
#0 /cygdrive/c/projects/tibia_login_php/xtea_tests.php(8): XTEA::encrypt('Hello, World!', Array, 0)
#1 {main}
thrown in /cygdrive/c/projects/tibia_login_php/xtea.class.php on line 73因为XTEA算法需要将数据加密成8个字节的倍数。但如果我们把它改成
<?php
require_once('XTEA.class.php');
$keys_binary = "secret";
$keys_array = XTEA::binary_key_to_int_array($keys_binary);
$data = "Hello, World!123";
$encrypted = XTEA::encrypt($data, $keys_array, XTEA::PAD_NONE);
$decrypted = XTEA::decrypt($encrypted, $keys_array);
var_dump($data, $encrypted, $decrypted);你会得到
string(16) "Hello, World!123"
string(16) "%t□□□n□□aʓ'□□H"
string(16) "Hello, World!123"发布于 2017-12-07 16:15:03
它应该与$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的大小,以确保它具有正确的长度,例如,使用您提到的PEAR模块Crypt_Xtea的_resize(&$data, $size, $nonull = false)函数。
https://stackoverflow.com/questions/47433135
复制相似问题