虽然我们拥有所有源代码,并且大多数文档都有据可查,但是安全性部分还是不是,特别是最慢的部分,是具有72个回合的128位哈希函数。我可以将其放入调试器中,执行它,除了运行缓慢以外,代码可以正常工作。如果我知道它是哪种加密标准,我可以尝试将其升级为在硬件中执行,这将大大加快其速度。 (编写此功能的原始顾问不在我们公司,而且我找不到她。)
是否有任何逻辑方法可以确定我们正在执行哪种加密?在帮助我完成工作时,我正在寻求建议,如果有任何策略可以查看代码(“未优化的混乱”);学习它的原理(像这样有72个回合并散列128位);然后找到做同样事情的候选标准。
我认为,找到已记录的标准后,我应该能够通过使用我们的哈希和标准哈希来哈希各种数字,并简单地查看结果匹配吗?
我在网上寻找了使用Skein算法的72轮已知函数的信息,但是找不到类似的东西。已知标准的值,例如哈希0的结果?此哈希将0转换为这16个十六进制字节:
ae c5 40 44 df 2d 91 1c 87 ab 1a ff 59 09 aa b7
函数的开头和结尾在下面,如您中某些人所要求的,完整功能在以下位置:
full_function_code
以前的程序员似乎让旧的C编译器进行了转换,然后以“汇编”样式使用了它。也许是因为避免编译器优化,这只是我的猜测。
有72个回合,每个回合以对函数
TricoreDextr()
的调用结束;与Infineon TriCore DEXTR指令的C等效项。认为DEXTR是将64位数字分为两部分(在选定的位位置)并交换它们。 > /*
* @param in_arr 16 byte long array, input data (128 bits)
* @param out_arr 16 byte long array, output data (128 bits)
*/
void Hash16bytes(unsigned char *in_arr, unsigned char *out_arr)
{
long d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d15;
long IN[16];
d4 = 0xB12E8FB5;
int i;
for (i = 0; i < 16; i++)
{
IN[i] = (long) (*(in_arr + i));
}
d11 = (IN[3] << 24) | (IN[2] << 16) | (IN[1] << 8) | IN[0];
d10 = (IN[7] << 24) | (IN[6] << 16) | (IN[5] << 8) | IN[4];
d12 = (IN[0xB] << 24) | (IN[0xA] << 16) | (IN[9] << 8) | IN[8];
d13 = (IN[0xF] << 24) | (IN[0xE] << 16) | (IN[0xD] << 8) | IN[0xC];
/* block like this below repeats 72 times... */
d3 = 0x7025BD47;
d8 = 0xCCEE4EFE;
d8 += d13;
d8 += d3;
d8 = TricoreDextr(d8, 6);
/*
etc., TricoreDextr is called total of 72 times
*/
d0 += d15;
d0 += 0x5C4E0000;
d0 -= 0x2EDC;
d0 = TricoreDextr(d0, 5);
*(out_arr + 3) = (unsigned char) ((d5 >> 24) & 0xFF);
*(out_arr + 2) = (unsigned char) ((d5 >> 16) & 0xFF);
*(out_arr + 1) = (unsigned char) ((d5 >> 8) & 0xFF);
*(out_arr + 0) = (unsigned char) ((d5) & 0xFF);
*(out_arr + 7) = (unsigned char) ((d6 >> 24) & 0xFF);
*(out_arr + 6) = (unsigned char) ((d6 >> 16) & 0xFF);
*(out_arr + 5) = (unsigned char) ((d6 >> 8) & 0xFF);
*(out_arr + 4) = (unsigned char) ((d6) & 0xFF);
d8 += d0;
d8 += 0x10320000;
d8 += 0x5476;
*(out_arr + 0xB) = (unsigned char) ((d8 >> 24) & 0xFF);
*(out_arr + 0xA) = (unsigned char) ((d8 >> 16) & 0xFF);
*(out_arr + 9) = (unsigned char) ((d8 >> 8) & 0xFF);
*(out_arr + 8) = (unsigned char) ((d8) & 0xFF);
*(out_arr + 0xF) = (unsigned char) ((d7 >> 24) & 0xFF);
*(out_arr + 0xE) = (unsigned char) ((d7 >> 16) & 0xFF);
*(out_arr + 0xD) = (unsigned char) ((d7 >> 8) & 0xFF);
*(out_arr + 0xC) = (unsigned char) ((d7) & 0xFF);
}
#1 楼
正如otus所说,这很可能是RIPEMD128损坏或非常类似的东西。 br />通常,当试图识别与密码相关的代码时,您依赖于发现常量。在这种情况下,常量似乎是故意被混淆了,因此您需要使用数字,将其放入Google并希望得出一些结果。 (通过不断的搜寻),我寻找了一些代码。因为输入/输出是128位,所以我从这里下载了RIPE128的代码:https://homes.esat.kuleuven.be/~bosselae/ripemd160/ps/AB-9601/rmd128 .c
然后我查看了一下。我注意到
compress()
中的操作似乎使用了向左旋转(检查宏定义的头文件),并且奇怪的TricoreDextr()
实际上是类似的东西。 TricoreDextr()
行,并将其与compress()
中的操作进行比较,并出现了一些相似之处:GG(aa, bb, cc, dd, X[ 7], 7);
GG(dd, aa, bb, cc, X[ 4], 6);
GG(cc, dd, aa, bb, X[13], 8);
GG(bb, cc, dd, aa, X[ 1], 13);
比较: br />。
TricoreDextr
调用未完全匹配rich128实现。我还注意到在这些操作中仅使用了一些幻数。例如出现在
d8 = TricoreDextr(d8, 7);
d6 = TricoreDextr(d6, 6);
d5 = TricoreDextr(d5, 8);
d7 = TricoreDextr(d7, 0xD);
出现:
#define GG(a, b, c, d, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s));\
}
,但其他却没有,所以肯定缺少一些如果是RIPE128的操作。在RIPE160(和RIPE128)之前,曾有一个128位RIPEMD哈希函数的原始设计,但我当时无法找到任何源代码。到
https://www.springer.com/in/book/9783540606406
,其中应该包含我认为的原始算法,但这是一本花钱的书。
知道了所有这些,我最好的猜测是这是故意混淆的原始RIPEMD 128位哈希函数,因为现代实现中有部分但不是全部操作都在这里,暗示它们可能是第二个版本的补充,它将解释他们为什么失踪。那人或某人使用了现代的RIPEMD128实现,并对它做了奇怪的事情。
评论
谢谢您提供的书链接,我订购了该书,它具有教育意义,甚至更多,它描述了代码
– EmbeddedGuy
18年4月25日在15:05
评论
您尚未显示如何在Hash16bytes()中填充out_arr []。另外,您的代码段中出现的常量(即:0xB12E8FB5、0x7025BD47、0xCCEE4EFE)不会出现在Google之外的任何地方,但会出现此问题,这使这个难题变得有些挑战。我可以推断出:1)此哈希函数是自生的,2)这是键控哈希函数,并且常量以某种方式表示键,或3)这是代码生成和/或以一种奇怪的方式转换的。 >mhum:我也添加了函数的结尾
该代码是未优化的烂摊子,几乎可以肯定不是标准的,您应该发布完整的链接,因为注释的块可能无法精确地重复
看起来它可能是模糊的RIPEMD-128。常量似乎匹配为0x5C4E0000-0x2EDC = 0x5C4DD124和0x50A30000-0x741A = 0x50A28BE6。应该易于确认。 (在这里,反向工程不在主题之列,标记为迁移。)
该代码看起来有些丑陋,但是您确实以源代码形式拥有它。为什么不分析一些运行并尝试按原样加快运行速度,而不是尝试查找看起来相似但产生稍微不同结果的另一种算法,从而破坏协议?