65,182
社区成员




下面是一个加密函数a1是明文a2是密钥a3是计算的结果,我的问题是有没有方法通过a1和a3计算出来a2的密钥是什么?
感谢指点
//数据加密
byte Calculation(unsigned char* a1, unsigned char* a2, unsigned char* a3)
{
char aa25[16];
char aa23[16] = { 0 };
unsigned char aa2[16] = { 0 };
for (int i = 0; i < 16; i++)
aa2[i] = a2[i];
for (int i = 0; i < 16; i++)
aa25[i] = a1[i] ^ aa2[i];
int v6 = 0;
while (1)
{
v6++;
for (int k = 4; k < 16; k++)
aa2[k] = aa2[k] ^ aa2[k - 4];
for (int l = 0; l < 16; l++)
aa23[(-3 * l & 0xF)] = aa25[l];
if (v6 == 10) //==后面是循环次数
break;
for (int m = 0; m < 16; m++)
aa25[m] = aa2[m] ^ aa23[m];
}
for (int result = 0; result < 16; result++)
a3[result] = aa23[result] ^ aa2[result];
return 0;
}
你好,你看一下私信,给你发了一条私信,请教代码的问题
我稍微研究了一下,你的新算法可能有大BUG,还不如之前的算法,上一个算法bao力po解是32位强度,这个只有16位强度。
假设先C(a1, a2, a3); 这里a2是密钥,对用户是未知的,用户只有加密程序、a1和a3
找到byte_8019EA8,修改为256字节全0,然后把a3作为源数据再加密一次:C(a3, a2, a4);
对得到的a4做一下简单处理:
for (int i = 0, v7[] = {1, 2, 4, 8, 16, 32, 64, 128, 27, 54}; i < 10; i++)
{
a4[0] = a4[0] ^ v7[i];
for (int j = 4; j < 16; j++) a4[j] ^= a4[j - 4];
}
这样就恢复了16字节密钥中的14字节(只有a4[8]和a4[12]是不对的),实际上,如果继续研究下去,我相信可以直接逆出来全部密钥,而不需要bao力po解,不过我不想再浪费时间了。
之所以说“可能有大BUG”,是要看应用场景,如果用户接触不到byte_8019EA8数据这部分,比如加密程序在服务器上,那就没有大问题,如果加密程序在客户端,即便不存储密钥(由用户输入的密码转换得到),也是不可靠的
这个byte_8019EA8也是密钥,当然不可能只依据a1、a3逆出a2~
byte_8019EA8是一个表?
(BYTE) * (&v23[(m & 0xC | (m + 1) & 3)])不就是v23[...]吗~
请看一下,下面的代码还有没有漏洞了?
//数据加密
byte Calculation(unsigned char *a1, unsigned char *a2, unsigned char *a3)
{
char v25[16];
char v23[16] = { 0 };
unsigned char aa2[16] = { 0 };
for (int i = 0; i < 16; i++)
aa2[i] = a2[i];
for (int i = 0; i < 16; i++)
v25[i] = a1[i] ^ aa2[i];
int v6 = 0;
while (1)
{
int v7 = 1 << v6;
v6++;
for (int j = 15; j > 7; j--)
{
if ((v7 >> j) & 1)
v7 = ((283 << (j - 8)) ^ v7);
}
aa2[0] = aa2[0] ^ byte_8019EA8[(BYTE)aa2[0x0D]] ^ v7;
aa2[1] = aa2[1] ^ byte_8019EA8[(BYTE)aa2[0x0E]];
aa2[2] = aa2[2] ^ byte_8019EA8[(BYTE)aa2[0x0F]];
aa2[3] = aa2[3] ^ byte_8019EA8[(BYTE)aa2[0x0C]];
for (int k = 4; k < 16; k++)
aa2[k] = aa2[k] ^ aa2[k - 4];
for (int l = 0; l < 16; l++)
v23[(-3 * l & 0xF)] = byte_8019EA8[(BYTE)v25[l]];
if (v6 == 10) //==后面是循环次数
break;
for (int m = 0; m < 16; m++)
{
int v12 = 2 * (BYTE) * (&v23[(m & 0xC | (m + 1) & 3)]) ^ 2 * (BYTE) * (&v23[m]) ^ (BYTE) * (&v23[(m & 0xC | (m + 1) & 3)]) ^ (BYTE) * (&v23[(m & 0xC | (m + 2) & 3)]) ^ (BYTE) * (&v23[(m & 0xC | (m + 3) & 3)]);
for (int n = 15; n > 7; n--)
{
if ((v12 >> n) & 1)
v12 = (283 << (n - 8)) ^ v12;
}
v25[m] = aa2[m] ^ v12;
}
}
for (int result = 0; result < 16; result++)
a3[result] = v23[result] ^ aa2[result];
return 0;
}
是你的测试代码没写对~
不对
他这个算法有漏洞,16字节密钥的第0、4、8、12字节可以直接逆出来:
a2[0] = a3[0] ^ a1[0];
a2[4] = a3[4] ^ a1[4] ^ a2[0];
a2[8] = a3[8] ^ a1[8] ^ a2[4];
a2[12] = a3[12] ^ a1[12] ^ a2[8] ^ a2[0];
其他三组,1/5/9/13、2/6/10/14、3/7/11/15各4字节,不能直接逆运算出来,但是可以bao力po解,其密钥强度只相当于32位,在现在的PC上也是极容易解决的。