能力值:
( LV2,RANK:10 )
|
-
-
2 楼
1、全查表需要占用5TB的硬盘空间。5TB是这样计算出来的:
5TB = (2^40) * 5,
其中 2^40 表示记录总数,5 表示每个记录要占用5字节。
如果采用差分保存技术,可以将5TB的需求降到2TB左右。
2、你的理解是对的,每个文件中的2^24个A(输入)按照映射关系都对应同一个输出B。根据5字节的B值来查表,对应文件中的2^24个A值都是“嫌疑”对象(可能的密钥),到底哪一个是“真凶”(加密该office文件的正确密钥),验证依据就是48字节随机数中后32字节的md5依赖关系。
3、将2^40个 B--A 函数对应关系摊分到2^16个文件中,每个文件保存2^24个对应关系,在每个文件内做快速排序,这样总的排序时间为
T = (2^16) * O( (2^24) * lg(2^24) ),
T 表达式中的前者为文件数,后者是每个文件内部快速排序的时间复杂度。
而对原始的2^40个记录进行快速排序的时间为 O( (2^40) * lg(2^40) ),
显然T大约是此值的1/2左右,所以分割后总效率上要高一点。
需要说明的是,这些讨论的技术都是基于自己来实施的假设。
如果你想利用那几个网站来进行破译,我们根本就不需考虑这些啦(网站帮我们实现了这些功能)。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
1、会不会存在根据客户端传回的B值而查询不到A值的情况?
2、有没有一些技巧方法能够方面快速的生成文件,并按照5字节ks(输出)B值来划分到同一个文件中呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
1、基本不存在这种情况,即可能性极小(采用彩虹链时失败概率小于千分之一),采用现在讨论的全查表方法的成功率为100%;
2、这个完全可以。根据Word加密机制,对2^40个输入A,依次计算其输出B时,根据情况分类存入到2^16个文件中去即可。但是,要注意的是,计算全部2^40个输入的输出值,这个任务在你的单机上是难以完成的,大约需要几个月的时间,所以真正实施时必须采用并行技术技术,多台机器同时做才行。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
thank!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
互相学习,共同提高。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
用过那个工具,旧版现在已经不好用了好像
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
"给定40比特(5字节)密钥 key 后,经由md5得到128字节的rc4密钥,再通过rc4加密算法(注:包括两个阶段)生产出5字节的伪随机数 ks (密钥流)。"
碰到个问题,rc4加密机制是将明文和密钥流进行异或就可以产生密文,我得到128的rc4密钥之后,是不是通过这个密钥再来加密“40比特(5字节)”,然后产生ks?
我的做法是这样的:
循环输入40比特key,加上固定的填充后生成一个64字节的数,再进行一轮标准的md5 hash后产生128位的结果(这个过程应该就是您说的“给定40比特(5字节)密钥 key 后,经由md5得到128字节的rc4密钥”)。后面的过程(再通过rc4加密算法(注:包括两个阶段)生产出5字节的伪随机数 ks (密钥流))我就不太明白了。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
“给定40比特(5字节)密钥 key 后,经由md5得到128比特的rc4密钥”这句话你的理解对了。
接下来就是根据这个128比特的密钥,按照RC4算法的两个阶段(密钥调度阶段KS和密钥流产生阶段)产生密钥流ks。本来密钥流可以无限长,但具体到我们的问题,其实只需要5字节的ks就够了。以后我们就是利用5字节ks来反向查表得到40bit密钥(输入)的。
注意:“有了128比特rc4密钥之后,不是通过这个密钥再来加密“40比特(5字节)”,而是按照RC算法产生ks,用ks再来加密明文的。这正是序列密码的一个基本特点,密钥流与明文通常是独立的。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
我就是不太明白怎样按rc4算法来产生ks,能不能根据你提供的rc4算法来详细说明一下,比如已经生成了128位的密钥(简称为C),那么怎样使用你改写的那个rc4算法来生成ks?
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
这个要好好看一下才懂哦
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
我提供的RC4代码有四个函数:
1. void RC4_KSA(UCHAR *rc4key, int KL, RC4_STATE *state);
2. void RC4_KSA_128(UCHAR *rc4key, RC4_STATE *state);
3. UCHAR RC4_PRGA(RC4_STATE *state);
4. void RC4(UCHAR *rc4key, int keylen, UCHAR *keystream, int kslen);
其中前2个函数负责密钥初始化(前者为密钥长度为KL字节的,后者专门为密钥长度为16字节的),函数3每次生成1字节密钥流ks,函数4其实是对前面三个函数的封装。
现在你经过MD5已得到了128比特(即16字节)的密钥K[],那么调用函数4:
RC4(K, 16, ks, 5);
即可得到5字节的ks。
不过这5字节是密钥流的最初5字节,在具体利用时可能不是这个位置的5字节,那些网站取的位置比较靠后,并且还不是连续的位置(有间隔),这些都是小问题,根据实际需要调用函数4生产足够长度的密钥流,再提取对应位置的数据即可。
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
这种方法理论和实践的产品有人做过的
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
当然有人做过啦,只是好像要花钱买的。
你觉得你能做吗?否则请不要这样子说话,有本事发表一点技术性的建议。OK?
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
这几天在调试程序来生成全查表,按照您说的,B值最多就是2的16次方个,但是我的程序输入不同A,都会产生一个不同的B值,比如输入2^20个A,就会输出2^20个不同的B值,也就是说B值都没有碰撞。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
输入A总共有2^40个,得到的输出B有2^40个,但这2^40个输出B是可能存在碰撞的(即不同的A对应到相同的B)。
你所说的输入2^20个A,就会输出2^20个不同的B值,也就是说B值都没有碰撞,这在实际中是可以存在的,并不矛盾。因为以上所说的是可能存在碰撞,但不一定碰撞。实际上这是一个概率问题,可以算出碰撞的可能性有多大。如果你把2^40个输入的输出都计算出来了,我感觉几乎一定会有碰撞的,还早呢,朋友。但我不知道你是否有这么大的计算能力(把所有2^40个都算一遍),你可以通过已计算2^20个结果来估算一下总时间。
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
这是生成128比特的代码,jeffcjh帮看看对不对,thanks!!!:
ArrayByteA = array [0..4] of byte;
Array16Byte = array [0..15] of byte;
function MakeKey(byteA: ArrayByteA):Array16Byte;
var
mdContext: MD5Context;
pwarray: array [0..63] of byte;
byteB: Array16Byte;
block: DWord;
begin
block := 0;
Fillchar(pwarray,sizeof(pwarray),0); //pwarray数组清零
CopyMemory(@pwarray, @byteA, 5); //拷过去40位(5个字节)
//put block number in byte 6...9
pwarray[5] := byte(block and $FF);
pwarray[6] := byte((block shr 8) and $FF);
pwarray[7] := byte((block shr 16) and $FF);
pwarray[8] := byte((block shr 24) and $FF);
pwarray[9] := $80;
pwarray[56] := $48;
//对pwarrey计算一轮标准的MD5 hash begin
MD5Init(mdContext);
MD5Update (mdContext, @pwarray, 64);
MD5StoreDigest(mdContext);
//对pwarrey计算一轮标准的MD5 hash end
CopyMemory(@byteB, @mdContext.Digest, 16);
result := byteB;
end;
生成byteB之后,就调用您的rc4函数来生成ks.
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
好好学习,天天向上
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
你的总体代码正确,但有一个细节我认为存在问题。
我认为你会C代码,我参考你的变量名,将这一块的正确C代码告知如下:
unsigned char byteA[9]; // byteA[]的前5字节赋值为输入A
unsigned char byteB[16];
unsigned char ks[512]; // 存储生产的密钥流(乱数), 具体长度自己确定
blockcnt = 0; // 加密块编号,初值为0x00000000
// byteA[]的第5至8字节赋值为块编号
*(unsigned int *)(byteA + 5) = blockcnt;
// 对9字节(不是64字节)作标准的MD5 !!!
MD5Data((unsigned char*)byteA, 9, byteB);
// 以16字节byteB[]做密钥, 根据RC4算法产生512字节乱数
RC4(byteB, 16, ks, 0x200);
说明:
可见这一块其实是很简单的,你应能明白。
我认为存在的问题就在对数组byteA[]9字节之后的填充上。我用C语言写的代码就是对byteA的9字节作标准的MD5得到16字节散列值byteB。由于对你的上述byteA填充不是很清楚,所以提出这个疑问供参考。
另外C语言数组的下标从0开始,VB是从0还是从1开始,这个边界小问题敬请注意。
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
按照您原来的说法,B值总共就只有2^16个,而现在我输入2^20个A值,就产生了2^20个不同的B值,这显然就已经不正确了啊。
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
不好意思,忘了对代码中的MD5进行说明,其C原型如下
unsigned char * MD5(const unsigned char *data, const unsigned int len, unsigned char *digest);
[in]参数data为数据首地址,
[in]参数len为数据长度,
[in, out]参数digest为最终输出的16字节md5散列值.
为方便使用,该函数实际上封装了标准MD5的三个函数,即函数实现为:
unsigned char * MD5(const unsigned char *data, const unsigned int len, unsigned char *digest)
{
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, data, len);
MD5Final(digest, &ctx);
return digest;
}
供参考,可以与你的VB版本的MD5进行比较使用。
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
md5的算法应该都是通用的。那估计就是我的生成128比特的代码有问题了。能否贴出这部分代码让我参考一下,到底是哪儿出错?生成对照表这个程序困扰我一个星期了。比较郁闷。
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
你理解错了,输入A共有2^40个,相应的输出B值也有2^40个啊。我说的是这2^40个输出B是存储到2^16个文件中去。对于输出B,到底存到2^16个文件中的哪一个中去呢?这要你自己定原则了,比如可以考虑按照B的最低2字节来分类,B的最低2字节相同的就存到同一个文件中,这样自然总共会产生2^16个结果文件。
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
那我觉得可能就是你对byteA[]9字节后的填充不对,就不用去填充,而是直接对9字节进行md5运算,具体代码我上面已经贴出来了啊。
|
能力值:
( LV2,RANK:10 )
|
-
-
25 楼
ok。我马上试一试看看。
|
|
|