首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >php实现(cfb)

php实现(cfb)
EN

Stack Overflow用户
提问于 2017-11-22 11:06:51
回答 2查看 562关注 0票数 1

我遇到了一种我无法理解的奇怪的行为。

我使用mcrypt (cfb模式)加密一些数据。由于php 7.2正在摆脱mcrypt,而且由于openssl不支持Xtea,所以我不得不自己实现该算法。

问题是,无论使用的算法是:

  • 我测试了这里提供的一个:pear实施,它只是一个欧洲央行模式(没有init向量)。
  • 在维基百科的网页上从这个stackoverflow主题上提供的
  • 我在这里开发的( CFB模式)是基于维基百科这里这里以及mcrypt源代码中的两篇文章,这两篇文章都可以找到这里: /* * $v是数据,$k是128位键,$iv是64位内向量(size = 8) *代码没有优化*/函数encryptCfb( $v,$k,$iv) {$v=array_values(解包(‘N*’,$v));$iv =array_values(解包(‘N*’,$iv));$k =array_values(解包(‘N*’,$k));$k= [];//IV使用128位密钥列表( $v0,$v1) =密码($iv,$iv1,$k)进行加密;//使用前64位数据( V0中的32位和V1中的32位)对密码块进行加密,$cipher =$v0^ $v;$cipher1 = $v1 ^ $v1;for ($i=2;$i < count($v);$i+=2) {//现在使用128位密钥列表对最新的“密码”数据进行加密($y,$i)=密码($密码$I-2,$密码$i-1,);//用第二个64位数据( V0中的32位,V1中的32位) $cipher$i = $y ^ $v$i;$cipher$i+1 = $z ^ $v$i+1;} $output = "";foreach ($cipher as $i) { $output .= pack('N',$i);}返回$output;}函数密码($v0,$v1,$v0;= 0;=* 32;($i=0;$i < 32;$i++) { $v0 += ($v1<<4)^ ($v1>>5)) + $v1) ^ ($sum + $k$sum & 3);$sum += $delta;$v1 += ($v0 << 4) ^( $v0 += 5)) +)^(+()& 3);}返回,;}

我得到了一个不同的结果,而且,没有一个结果与mcrypt给出的结果完全相同:

代码语言:javascript
复制
$cryptModule = mcrypt_module_open('xtea', '', 'ncfb', '');
mcrypt_generic_init($cryptModule, $key, $iv);
mcrypt_generic($cryptModule, $data);

您可以使用相同的数据/key/IV检查和测试我在这里进行的不同测试:

  • 我在CFB模式下实现与mcrypt的比较。请注意:
代码语言:javascript
复制
- The number of rounds changes nothing (32 or 64)
- Packing/Unpacking using N mode (big endian) or V mode (little endian) changes nothings 

  • PEAR模式与mycrypt ECB模式
  • CBC模式下的wiki代码与cbc模式下的mcrypt

有人知道我为什么会得到不同的结果吗?

EN

回答 2

Stack Overflow用户

发布于 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

示例

代码语言:javascript
复制
<?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);

应该输出如下这样的内容:

代码语言:javascript
复制
string(13) "Hello, World!"
string(16) "□□Jx□□□□□□□ܴ9"
string(16) "Hello, World!   "

长度是不同的,因为x茶长度填充,可以通过以下方式禁用

代码语言:javascript
复制
XTEA::encrypt($data, $keys_array, XTEA::PAD_NONE);

这会给你:

代码语言:javascript
复制
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个字节的倍数。但如果我们把它改成

代码语言:javascript
复制
<?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);

你会得到

代码语言:javascript
复制
string(16) "Hello, World!123"
string(16) "%t□□□n□□aʓ'□□H"
string(16) "Hello, World!123"
  • 没有填充,没有长度变化,也没有例外。
票数 2
EN

Stack Overflow用户

发布于 2017-12-07 16:15:03

它应该与$v0和$v1上的模数一起工作:

代码语言:javascript
复制
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)函数。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47433135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档