时间: 2021-08-13 作者:daque
对于access97的暗号破译,在很多的网站和期刊上都有过引见。在这边我大略反复一下。 在mdb文献第0x42字节处的13个字节辨别与0x86,0xfb,0xec,0x37,0x5d,0x44,0x9c,0xfa,0xc6,0x5e,0x28,0xe6,0x13异或后即可获得数据库的暗号。但在access 2000和2002的本子里密钥不复是恒定的13个字节.并且加密的办法也有了变革。 过程ccrun用一下昼的功夫接洽,毕竟将access2000的加密办法搞领会了。嘿嘿。在此将偶的心得颁布。蓄意对大师有效,即使您创造我的领会有误,请来函告之咱们。邮箱:info@ccrun.com 版权固然有没有都不妨,然而即使您要连载,请证明根源,并保护文书档案的完备性。感谢。 我用的领会东西是ultraedit32 v10.00,编制程序东西是c++ builder 6.0 过程用ultraedit32领会,创造access2000和access2002的数据库加密办法沟通,以是以次只对准access2000的mdb文献。再有即是我用的是16进制的数表白,以是前方加了0x,即使你用的是vb或其余,要提防数值哦。 开始用accessxp创造了一个空暗号的数据库文献db1.mdb,包括一个表,个中有一个字段,没有填任何数据。生存退出而后复制一份为db2.mdb,以独吞办法翻开2.mdb,并加上暗号1324567890123 生存退出。 用ultraedit32翻开这两个数据库,并举行比拟。我比拟的本领也很大略。在ultraedit3第22中学,赶快的往返点击被翻开文献的选项卡(即是在两个文献间往返切换,呵呵。笨方法吧),创造从文献头发端0x42字节处爆发变革。 db1.mdb 00000040h:bc 4e be 68 ec 37 65 d7 9c fa fe cd 28 e6 2b 25 ; 00000050h: 8a 60 6c 07 7b 36 cd e1 df b1 4f 67 13 43 f7 3c ; 00000060h:b1 33 0c f2 79 5b aa 26 7c 2a 4f e9 7c 99 05 13 ; db2.mdb 00000040h:bc 4e 8f 68 de 37 56 d7 a8 fa cb cd 1e e6 1c 25 ; 00000050h: b2 60 55 07 4b 36 fc e1 ed b1 7c 67 13 43 f7 3c ; 00000060h:b1 33 0c f2 79 5b aa 26 7c 2a 4f e9 7c 99 05 13 ; 为了看的领会些,我把各别的字节加了脸色。看外出道了吧,access97此后的本子里,暗号字节不复是贯串寄存,而是隔一个字节存一个。而且过程加密。到于解密的本领嘛,仍旧用老方法“异或”!0xbe ^ 0x8f = 0x31,这凑巧是ascii码"1"哦。下一个0xec ^ 0xde = 0x32 凑巧是ascii码"2",呵呵。从来到结果一个各别的0x4f ^ 0x7c =0x33,将博得的字适合成字符串,便是暗号明文“1234567890123",万万不要觉得如许就竣工了。由于这一次是凑巧碰对了。呵呵。我刚发端也觉得就这么大略,所以用cb做了个小步调,试着解了几个mdb暗号都还行,然而试到动网乒坛的mdb文献时创造掏出来的暗号不对,晕了。所以用其余一个取mdb暗号的东西看了一下,创造人家的就不妨精确的掏出暗号,是access2000的方法,所以发觉微软加密的办法仍旧没接洽完。连接处事,用ultraedit32打启动网乒坛的数据库dvbbs.mdb,和我前方的加过密的数据库做比拟,创造各别的场合很多。只好一个字节一个字节的试。。。。nnn次此后创造第0x62处的这个字节起着要害效率,暂称之为加密标记。 db1.mdb //空暗号 00000040h:bc 4e be 68 ec 37 65 d7 9c fa fe cd 28 e6 2b 25 ; 00000050h: 8a 60 6c 07 7b 36 cd e1 df b1 4f 67 13 43 f7 3c ; 00000060h:b1 33 0c f2 79 5b aa 26 7c 2a 4f e9 7c 99 05 13 ; db2.mdb //暗号为:1234567890123 00000040h:bc 4e 8f 68 de 37 56 d7 a8 fa cb cd 1e e6 1c 25 ; 00000050h: b2 60 55 07 4b 36 fc e1 ed b1 7c 67 13 43 f7 3c ; 00000060h:b1 33 0c f2 79 5b aa 26 7c 2a 4f e9 7c 99 05 13 ; dvbbs.mdb //暗号为:yemeng.net 00000040h:bc 4e db 6a 89 37 14 d5 f9 fa 8c cf 4f e6 19 27 ; 00000050h: e4 60 15 05 0f 36 d1 e3 df b1 53 65 13 43 eb 3e ; 00000060h:b1 33 10 f0 79 5b b6 24 7c 2a 4a e0 7c 99 05 13 ; 如何试呢,仍旧异或。取0x42处发端的字节0xdb与空暗号文献的0x42处字节异或,取0x62处的加密标记与空暗号文献0x62处字节异或,而后再把博得的两个值相异或: (0xdb^0xbe)^(0x10^0x0c)=0x79 嘿嘿。这个值是ascii的"y",而后取下一个字节(牢记隔一个字节取一个) (0x89^0xec)^(0x10^0x0c)=0x79 咦,从来这个字节该当是"e"的,如何形成"y"了?试着不与反面的两个异或值相异或,只计划0x89^0xec=0x65 获得"e",哈。这下对了。下一个 (0x14^0x65)^(0x10^0c)=0x6d 获得"m",下一个 (0xf9^9c)=0x65 获得"e",提防这边不过这两个数异或。反面的大师不妨本人试。 如许就归纳出顺序来了。 解密时,先掏出加密文献从文献头发端0x62处的字节,与空暗号数据库文献第0x62处相异或,获得一个加密标记。 再从0x42处发端每隔一个字节取一个字节,博得13个加密后的暗号字节,辨别与空暗号数据库文献0x42处每隔一个字节博得的13个字节想异或,获得13个暗号半制品。干什么说是半制品呢,由于还要将13个字节的暗号每隔一个字节,就与加密标记相异或,结果获得的13个字节才是真实的暗号。固然,即使中央有0x0的字节,则证明暗号位数不够13位。径直show出来就不妨了。 其余我创造加密标记会跟着功夫或呆板各别而各别,以是也没有全能的,然而有一个参照的就不妨了。以次代码是我在写这个步调的功夫博得的数,和我写这篇作品不是一个功夫,以是数值不一律,但最后解密的截止是一律的。大师不妨参考一下。 对了,再有个要害的即是先得确定数据库的本子,我用了个大略的方法,取0x14处的字节,即使为0就确定为是access97,即使为1就觉得是access2000或2002的。不过暂时没有接洽出确定2000和2002的方法,即使哪位领会的话,请引导。 代码: //这边设置的是13个字节动作access2000异或的源码。与之对立应的加密标记是0x13,ccrun特此证明 //固然你不妨用这一组: be ec 65 9c fe 28 2b 8a 6c 7b cd df 4f 与这一组对立应的加密标记是0x0c //呵呵.步调有些乱,蓄意大师能看的懂。 char passsource2k[13]={0xa1,0xec,0x7a,0x9c,0xe1,0x28,0x34,0x8a,0x73,0x7b,0xd2,0xdf,0x50}; //access97的异或源码 char passsource97[13]={0x86,0xfb,0xec,0x37,0x5d,0x44,0x9c,0xfa,0xc6,0x5e,0x28,0xe6,0x13}; void __fastcall tmainform::getmdbpass() { char passstrtemp[26],ver,encrypflag,t1; int filehandle; string mdbpassword,mdbversion,mdbfilename; filehandle=fileopen(mdbfilename,fmopenread); if(filehandle<0) { showmessage("文献翻开缺点!"); return; } //博得数据库本子 fileseek(filehandle,0x14,0); fileread(filehandle,&ver,1); //博得加密标记 fileseek(filehandle,0x62,0); fileread(filehandle,&encrypflag,1); //读取加密后的暗号到缓冲区 fileseek(filehandle,0x42,0); fileread(filehandle,&passstrtemp,26); fileclose(filehandle); if(ver<1) { mdbversion="access 97"; if(int(passstrtemp[0]^passsource97[0])==0) mdbpassword="暗号为空!"; else { mdbpassword=""; for(int j=0;j<13;j++) mdbpassword=mdbpassword+char(passstrtemp[j]^passsource97[j]); } } else { mdbversion="access 2000 or 2002"; mdbpassword=""; for(int j=0;j<13;j++) { if(j%2==0) t1=char(0x13^encrypflag^passstrtemp[j*2]^passsource2k[j]); //每隔一个字节就与加密标记相异或。这边的加密标记为0x13 else t1=char(passstrtemp[j*2]^passsource2k[j]); mdbpassword=mdbpassword+t1; } } if(mdbpassword[1]<0x20||mdbpassword[1]>0x7e) mdbpassword="暗号为空!"; editmdbfilename->text=mdbfilename; editmdbpassword->text=mdbpassword; editmdbversion->text=mdbversion; }