首页
社区
课程
招聘
[原创]无KEY还原简单XOR加密字符探索
2007-4-5 23:38 14773

[原创]无KEY还原简单XOR加密字符探索

2007-4-5 23:38
14773
作者:笨笨雄
工具:VC

首先看看XOR的运算规则:

1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 0 = 0
1 XOR 1 = 0

注意到下面的规律:

p XOR k = c,c XOR k = p,p XOR c = k

把P看成明文,通过XOR运算后得到密文C,那么K值便是密钥。因此XOR常用于加密。由于简单,而且速度很快,常用于简单的字符加密,以对抗字符参考。本文仅讨论使用8位key,只作一次xor运算的情况。尽管安全性很差(p xor c = k),但是大家都喜欢用简单的方法

先从最简单的ASCII编码开始。它包括26个英文字母和10个数字以及一些符号。单字节的编码,而且最高位一般情况下为0。由于每个字节都由固定的KEY进行XOR加密,因此检查每一个字节的最高位是否相同,便能知道处理的字符是否为ASCII编码。

我们知道,英文使用空格(0x20)来分隔每一单词。这样便为我们提供了另外一个攻击XOR加密字符的途径。我猜想“congratulation!”大概是注册文本信息中可能出现的最长的一个单词。它的长度是15,也就是说我们可以从第16个字节开始,将密文XOR 0x20,得出KEY。现在需要穷举的KEY数量就只有15(我假设第一个字符不会为空格,最短的单词大概就只有i和a了。)

现在我们需要做的只是为注册信息中可能出现的单词建立一个字典,测试每一个KEY。下面是实现的C代码片段:
	numread = fread (buffer,sizeof(char),150,srcfile);

	for(a=16; a != 0; a--)
	{
			ckey = buffer[a] ^ 0x20;   //从16字节开始xor 0x20
			for (i=0; i != a; i++)
				decode[i] = buffer[i] ^ ckey; //尝试用该key解密
			if (bingo = KeyCheck(decode))  //keycheck测试key是否正确
				break;
	}

/*-----------------------------------------------------------------------
无key还原简单XOR字符示例
Code by 笨笨雄/www.pediy.com

下面是判断KEY是否正确的函数
------------------------------------------------------------------------*/
char *map[10]=               //字典
{
	"key",
	"valid",
	"congratulation",
	"is",
	"thanks",
	"the",
	"register",
	"to",
	"please",
	"full"
};

bool KeyCheck(char *pDecode)
{
	int Counter,Slength;

/*---------------------------------------------------------------------
此处假设得到的密文是整段字符的起始位置,只比较第
一个单词是否匹配。为了应付更复杂的情况,应在整个
解密缓冲区中搜索字典中的单词。恩,我有点懒
---------------------------------------------------------------------*/
	for (Counter = 0; Counter != 10; Counter++)
	{
		Slength = strlen(map[Counter]);
		if((_strnicmp(map[Counter],pDecode,Slength))==0) 
			return true;
	}
	return false;
}

附件中的XOR.exe用于对文本文件进行XOR加密。具体格式为xor srcfile outfile。按提示输入加密的KEY便可以生成演示所需要的加密文件。Ascii.exe为解密示例程序。

按照上述思路扩展,也可以解密一些被加密的链接信息。可以假定www或者http之类的信息。然而对于中文却无能为力。或许你会想到用逗号或者句号,天知道一句话里面多少个字之后才会有逗号?你甚至可能连句号都看不到,还有问号感叹号什么的。因此,我们需要另一种思路。

注意到KEY只有8位的假设,以及p xor c = k。也就是说,比较可能出现的明文和密文XOR得出的KEY,如果相等,我们便找到真正的KEY了。这种方法更加灵活,由于字符始终要被解密出来的,通过人工输入软件中出现的字符,便能解密出其他字符,记录成功解密的字符,完善自动解密的字典。下面是简单的示例代码片段:
char *map[10]=    //中文字典
{
	"失败",
	"恭喜",
	"成功",
	"授权",
	"支持",
	"用户",
	"注册",
	"限制",
	"功能",
	"联系"
};
/*-----------------------------------------------------------------------
无key还原简单XOR字符示例
Code by 笨笨雄/www.pediy.com
------------------------------------------------------------------------*/
	numread = fread (buffer,sizeof(char),150,srcfile);
	bingo=false;
	
	for (j = 0; j != numread; j++)
	{
		for (a = 0; a != 10; a++)
		{
			Slength = strlen(map[a]);
			t_Byte = (*map[a]);    //从字典中取字符
			tKey = buffer[j] ^ t_Byte; //获得第一个KEY
			counter = 1;
		
			for (i = 1; i != Slength ; i++)
			{
				p_Byte = map[a] + i;
				t_Byte = (*p_Byte);
				ckey = buffer[j+i] ^ t_Byte;
				if (ckey == tKey) //测试其他的KEY是否相同
					counter++;
			}

			if (counter == Slength)
			{
				bingo=true;  //相同的次数等于字符长度
				break;      //则认为找到KEY
			}
		}
		if (bingo)
			break;
	}

附件中的DecodeXor.exe便是示例程序,gbk.txt和ascii.txt为示例文本。你可以在附件中的src文件夹中找到相应的源代码。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (17)
雪    币: 28219
活跃值: (6650)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
风间仁 19 2007-4-6 00:59
2
0
这方法对于防字符参考挺有效的 ,学习中。。
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
bxm 29 2007-4-6 12:24
3
0
好文,支持!
雪    币: 243
活跃值: (11)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
edisonH 3 2007-4-6 22:41
4
0
a xor k=a1
b xor k=b1

|a-b|=|a1-b1|
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
笨笨雄 14 2007-4-7 13:41
5
0
果然我学得还没到家,还有4楼说的规律想不到。。。
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
scship 2007-4-7 17:11
6
0
都是离散达人。。。
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
WisdomZh 2007-4-9 21:01
7
0
好文, 支持并收藏
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pro先生 2007-4-10 21:01
8
0
我也不太懂,还在学习!
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pro先生 2007-4-10 21:02
9
0
我也不太懂,还在学习!
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pro先生 2007-4-10 21:02
10
0
我也不太懂,还在学习
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
peilan 2007-4-11 01:21
11
0
不用连说三遍吧?
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
eastboy 2007-9-14 14:13
12
0
简单的东西还是很有用 的
雪    币: 1309
活跃值: (232)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
deepwater 2007-9-14 21:24
13
0
居然有人相信如此谬论
雪    币: 8188
活跃值: (4238)
能力值: ( LV15,RANK:2459 )
在线值:
发帖
回帖
粉丝
ccfer 16 2007-9-14 21:53
14
0
a=5
b=2
k=2
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 10 2007-9-15 16:42
15
0
不是英文就难搞了。
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
笨笨雄 14 2007-9-15 22:49
16
0
看完论坛FTP那本密码学的书,之后试着写出来的文章。。。只想到已知明文攻击去解XOR。。。
发觉自己真的没什么密码学的天赋。。。然后就一直没再学了
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 10 2007-9-16 14:48
17
0
破解密码是个庞大的工程。不是靠一个人的天赋的。
除了基本的数学运算。关键是语言学。
在不知道明文的情况下。如何判定解密结果是有意义的是关键。
主要还是靠情报系统。而不是从数学的角度解决。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gxqcn 2007-9-17 13:44
18
0
这是怎么得到的?

取 a=3, b=4, k=5,则 |a-b|=1≠|a1-b1|=|6-1|=5
游客
登录 | 注册 方可回帖
返回