能力值:
( LV2,RANK:10 )
|
-
-
76 楼
这几天主要逛黑防去了,没留意你的问题。
通常情况下,Word是按照512字节一块(Excel按照1024字节一块)进行加密或解密的。
当你通过某种方式(比如上面讨论的查表方式)得到了40比特密钥,则按照加密机制可以生产乱数,每生产好512字节的乱数,就要将块号计数器增1,生成新的rc4密钥,再生产512字节乱数,如此重复,直至达到你的密文长度。将全部生产好的乱数与密文异或即得明文。
|
能力值:
( LV2,RANK:10 )
|
-
-
77 楼
您前面说过“乱数 = 密文 xor 底码”,我已经得到了40比特密钥,不知道怎样通过这密钥来产生乱数?
|
能力值:
( LV2,RANK:10 )
|
-
-
78 楼
得到40bit密钥后,对密文的解密大致如下所示:
unsigned char byteA[9]; // byteA[]的前5字节赋值为输入A
unsigned char byteB[16];
unsigned char ks[512]; // 存储每次生产的512字节乱数
blockcnt = 0; // 加密块编号,初值为0x00000000,以后递增
do
{
// 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);
//使用512字节乱数对密文解密...
//解密公式为:底码 = 密文 xor 乱数
} while (密文没有结束); // 注意:每次读512字节密文
你可以先用已得到的40bit密钥解密测试一下,针对blockcnt = 0和blockcnt = 1这两块密文,
它们对应的Word数据分别是Word文件的偏移0x200和0x400,每块均读512字节。
|
能力值:
( LV2,RANK:10 )
|
-
-
79 楼
这句代码
*(unsigned int *)(byteA + 5) = blockcnt;
应该为
*(unsigned int *)(byteA + 5) = blockcnt++;
|
能力值:
( LV2,RANK:10 )
|
-
-
80 楼
感谢ING。。。马上去测试。
|
能力值:
( LV2,RANK:10 )
|
-
-
81 楼
看雪这个输入编辑框也太小了,随便一输就满了,不好看清全部内容,难免出错。
|
能力值:
( LV2,RANK:10 )
|
-
-
82 楼
问个问题:
WORD97、WORD2000、WORD2002和WORD2003的加密解密算法是不是一样的?
|
能力值:
( LV2,RANK:10 )
|
-
-
83 楼
我用已得到的40bit密钥解密测试一下,针对blockcnt = 0和blockcnt = 1这两块密文,得出的结果与加密之前的值不相同。
我对比了同一个文件的加密前和加密后的文档,从0x000-0x243的数据基本上都是一样的,其中只有0x020b和0x020e不同。
|
能力值:
( LV2,RANK:10 )
|
-
-
84 楼
WORD97、WORD2000、WORD2002和WORD2003在使用默认的40比特密钥加密是过程都是一样的,除非用户选择其他加密类型。
解密后和解密前的数据不完全一致,这主要是Word在加密时对原来的明文数据进行了重新调整。判断你的40bit密钥是否正确只需看解密后的数据是否象明文(不是乱码)即可。
|
能力值:
( LV2,RANK:10 )
|
-
-
85 楼
解密后的数据与加密前的数据相差很远。这是我的代码,您看看有啥问题吗?
ByteA[0] := 49;
ByteA[1] := 109;
ByteA[2] := 90;
ByteA[3] := 10;
ByteA[4] := 4;
ByteA[5] := 0;
ByteA[6] := 0;
ByteA[7] := 0;
ByteA[8] := 0;
if not FileExists(sPath+'\'+sFileName) then Exit;
f := TFileStream.Create(sPath+'\'+sFileName, fmOpenRead);
nPos := 0;
nSize := f.Size;
try
while nPos < nSize do
begin
f.Seek(nPos, soBeginning);
f.ReadBuffer(ks, 512);
CopyMemory(@ks1, @ks, 512);
nPos := nPos + 512;
MD5Init(mdContext);
MD5Update (mdContext, @ByteA, 9);
MD5Final(mdContext);
CopyMemory(@byteB, @mdContext.Digest, 16);
RC4(byteB,16,ks,512);
for i := 0 to 511 do
ksDrypt[i] := ks[i] xor ks1[i];
ByteA[5] := ByteA[5] + 1;
end;
finally
f.Free;
end;
ksDrypt是最后得到的结果,与加密前的数据想对比相差很远。
|
能力值:
( LV2,RANK:10 )
|
-
-
86 楼
感觉代码细节上有点问题:
1、语句 f.Seek(nPos, soBeginning); 是定位到nPos开始读加密文件的数据吧?我认为nPos的初始值应该是512
|
能力值:
( LV2,RANK:10 )
|
-
-
87 楼
如果解密结果看起来乱七八糟,肯定是某个地方有问题。
|
能力值:
( LV2,RANK:10 )
|
-
-
88 楼
nPos := 0;
...
f.Seek(nPos, soBeginning);
f.ReadBuffer(ks, 512);
这几行代码的意思是从0开始定位,每次读取512字节。是从0开始读取还是从第512个字节开始读取?
|
能力值:
( LV2,RANK:10 )
|
-
-
89 楼
因为块号0对应Word文件的偏移0x200,块号1对应偏移0x400,所以应该是从word文件的第512个字节开始读取,逐块(512字节/块) 解密.
|
能力值:
( LV2,RANK:10 )
|
-
-
90 楼
意思是说:先把从0-512个字节的数据原封不动的先复制到新文件中,然后在从第512个字节开始逐块读取512个字节/块来解密?
|
能力值:
( LV2,RANK:10 )
|
-
-
91 楼
是的,你先这样试试
|
能力值:
( LV2,RANK:10 )
|
-
-
92 楼
这样的结果也不正确:
加密前的文件的数据
0x200 EC A5 C1 00 35 40 09 04 00 00 F0 52 BF 00 00 00
0x210 00 00 00 10 00 00 00 00 00 06 00 00 07 08 00 00
0X220 0E 00 62 6A 62 6A CF 32 CF 32 00 00 00 00 00 00
0X230 00 00 00 00 00 06 00 00 00 00 00 00 04 08 16 00
0X240 32 10 00 00 AD 58 00 00 AD 58 00 00 07 00 00 00
加密后的文件的数据
0x200 EC A5 C1 00 35 40 09 04 00 00 F0 53 BF 00 34 00
0x210 00 00 00 10 00 00 00 00 00 06 00 00 07 08 00 00
0X220 0E 00 62 6A 62 6A CF 32 CF 32 00 00 00 00 00 00
0X230 00 00 00 00 00 06 00 00 00 00 00 00 04 08 16 00
0X240 32 10 00 00 D3 C0 1A 7F 16 4B 14 CB E2 6C FC 6F
使用程序解密之后的数据
0x200 24 B5 CF C2 DC 51 28 3C 9D 2F 96 C4 D0 CA 1D 36
0X210 3F A0 D8 64 18 48 69 BE 6C 49 AA 63 CF AD D4 86
0X220 0A A3 3F 63 5D BF 89 4D BF C2 D3 5E EB 34 B6 41
0X230 51 4D BF 96 8E 7B CF BD 52 83 41 FB E4 19 34 AE
0X240 9B 37 62 D5 C7 A3 D2 66 FD 75 D3 2E 36 CF 14 97
|
能力值:
( LV2,RANK:10 )
|
-
-
93 楼
那你的40bit密钥是否正确?
|
能力值:
( LV2,RANK:10 )
|
-
-
94 楼
相关道理已经讨论得很多,也没有更多要说的了。
希望你一步步来,找到问题之所在。
|
能力值:
( LV2,RANK:10 )
|
-
-
95 楼
哦。我使用WORD2003的密码所对应的40bit密钥来解密WORD2002的同样的密码所加密的文档了,现在密钥已经改过来了,是对的,解密之后word文档打不开,提示说:
文档的名称或路径无效。请试用如下建议:
*检查文档或驱动器的文件权限;
*使用“文件”菜单中的“打开”命令来定位文档
我使用ultraedit打开解密之后的word文档,在0xa00处看到了加密之前文档的正确的内容(WORD文档的加密之前的内容为“000000”),但是从0x1232位置到最后0x4df0位置的数据就完全不一样了。
|
能力值:
( LV2,RANK:10 )
|
-
-
96 楼
好的,非常感谢您!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
97 楼
你快接近成功了。但还有几点技术细节需要掌握才能使用Word软件本身打开解密后的文件。
1、解密后文件偏移第0x20b字节的最低比特位需要强制修改为0(该比特若为1,则表示Word文件是加密的);
2、Word加密文件中有两大段密文,第一段从文件偏移0x200开始,第二段从以前说过的“01 00 01 00”(后接48字节随机数)开始。针对这两大段密文需要分别解密,特别是对第二段密文解密时乱数要重新生产(块号从0开始递增);
3、第一段密文(偏移0x200)解密时,其首部0x44字节不要xor乱数,即保持原样(除了第0x20b字节最低比特位置0外)。
剩下的就只有这些东西了,good luck to you.
|
能力值:
( LV9,RANK:170 )
|
-
-
98 楼
我等待结论final--tool
|
能力值:
( LV2,RANK:10 )
|
-
-
99 楼
thank you!您是我在网上见过的最乐于帮助的人。
|
能力值:
( LV2,RANK:10 )
|
-
-
100 楼
明白了。。。。。。
|
|
|