第29课 密码学算法二之 RSA.docx
《第29课 密码学算法二之 RSA.docx》由会员分享,可在线阅读,更多相关《第29课 密码学算法二之 RSA.docx(19页珍藏版)》请在冰豆网上搜索。
第29课密码学算法二之RSA
第29课密码学算法
(二)之RSA
*******************************************************************************
预备理论知识(比较枯燥):
RSA算法是第一个既能用于数据加密也能用于数字签名的算法。
它易于理解和操作,也很流行。
算法的名字以三个发明者的名字命名:
RonRivest、AdiShamir和LeonardAdleman。
RSA的基础是数论的欧拉定理,它的安全性依赖于大数因数分解的困难性。
但RSA的安全性一直未能得到理论上的证明。
它经历了各种攻击,至今未被完全攻破。
RSA密码系统为每个用户分配两对密钥(公钥和私钥),即公钥(e,n)和私钥(d,n),其中(e,n)用于加密报文,(d,n)用于解密报文,广泛应用于加密和数字签名方面,如现在已延伸到电子纳税申报,公钥或者私钥都可用作加密。
RSA加密算法的过程是:
(1)取两个素数p和q(保密);
(2)计算n=p×q(n称为模数,公开),φ(n)=(p一1)×(q一1)(保密);
(3)随机选取整数e(e称为公钥,公开),且满足gcd(e,φ(n))=1
(即e与(p一1)×(q一1)互素);
(4)计算d,满足de=1(modφ(n))(d称为私钥,保密)。
利用RSA加密,第一步需要将明文数字化,并取长度小于lg2n位的数字做明文块。
加密算法C=E(M)=Me(modn),其中,M为明文,C为密文。
解密算法M=D(C)=Cd(modn),用私钥d对密文C解密,得到明文M。
例如:
假定用户A要将明文“HI”加密传递给用户B,则B可以取两个素数p=5和q=11(保密);计算n=p×q=5×11=55(公开,公钥),φ(n)=(p一1)×(q一1)=4×10=40(保密);随机选取整数e=3(公钥),满足gcd(e,φ(n))=1;由de=1(modφ(n))得d=27(保密,私钥)。
因为,27×3mod40=81mod40=1
利用RSA加密,第一步需要将明文数字化,假定A、B统一明文编码方式为空格=00,A=01,B=02,C=03,...Z=26,则明文数字化HI为08、09,A用B的公钥(3,55)将数字化明文信息由C=E(M)=Me(modn)=83mod55、93mod55,加密得密文信息为l7、l4。
用户B收到密文信息由M=D(C)=Cdmodn=1727mod55、1427mod55解密得O8、O9,将其转化为明文“HI”。
(3)解密:
M=Cdmodn,用私钥d对密文C解密,得到明文M。
*******************************************************************************
[例1]dihux的keygenme1.exe
读程序的“关于”,写明为RSA200,但这是crackme。
我们所对付的一般程序是不会告诉你所采用的密码学算法的,我们需要自己用鼻子把她的气息闻出来、嗅探出来。
用peid扫描目标程序,用kanal插件分析,如图1
图1kanal扫描的结果
点“Export”按钮,将扫描结果保存为文件,如下:
Cryptoname:
:
Fileoffset:
:
Virtualaddress
密码文件偏移RVAVA内存虚拟地址
BASE64table:
:
00001BEE:
:
004041EE
BigLibBigMod:
:
00001406:
:
00402006
BigLibBigPowMod:
:
00001604:
:
00402204
{Bignumber}:
:
00001A1F:
:
0040401F
BigPowMod可以看出,采用了RSA算法。
同时,明确地告诉我们,编程时采用了BigLib库。
下面,用IDAPro打开目标程序,利用图2的字符参考
图2字符参考
很容易来到这里,即图3
图3
很难看出程序在干什么,可读性极差。
下面按如图4所示的菜单操作
图4
图5选取biglib
程序代码变为图6:
可读性大大提高。
关键代码如下:
xorecx,ecx
.text:
004010DA
.text:
004010DAloc_4010DA:
;CODEXREF:
DialogFunc+BD_j
.text:
004010DApush0
.text:
004010DCcall__BigCreate@4;_BigCreate(x)
.text:
004010E1movlpAddress[ecx*4],eax
.text:
004010E8incecx
.text:
004010E9cmpecx,6
.text:
004010ECjnzshortloc_4010DA
.text:
004010EEpushlpAddress
.text:
004010F4push10h
.text:
004010F6pushoffseta8acfb4d27cbc8c;"8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3B"...
.text:
004010FBcall__BigIn@12;_BigIn(x,x,x)
.text:
00401100pushdword_404415
.text:
00401106push10h
.text:
00401108pushoffsetunk_404019
.text:
0040110Dcall__BigIn@12;_BigIn(x,x,x)
.text:
00401112pushdword_404425
.text:
00401118push10h
.text:
0040111Apushoffsetbyte_404349
.text:
0040111Fcall__BigIn@12;_BigIn(x,x,x)
.text:
00401124pushoffsetString;lpString
.text:
00401129calllstrlenA
.text:
0040112Epushdword_404419
.text:
00401134pusheax
.text:
00401135pushoffsetString
.text:
0040113Acall__BigInB256@12;_BigInB256(x,x,x)
.text:
0040113Fpushdword_404421
.text:
00401145pushlpAddress
.text:
0040114Bpushdword_404415
.text:
00401151pushdword_404425
.text:
00401157call__BigPowMod@16;_BigPowMod(x,x,x,x)
.text:
0040115Cmoveax,1337h
.text:
00401161push0
.text:
00401163pushdword_40441D
.text:
00401169pusheax
.text:
0040116Apushdword_404421
.text:
00401170call__BigDiv32@16;_BigDiv32(x,x,x,x)
.text:
00401175pushdword_40441D
.text:
0040117Bpushdword_404419
.text:
00401181call__BigCompare@8;_BigCompare(x,x)
.text:
00401186jnzshortloc_40119C
.text:
00401188push0;uType
.text:
0040118ApushoffsetCaption;"iNFO"
.text:
0040118FpushoffsetText;"Serialisvalid"
.text:
00401194push[ebp+hWnd];hWnd
.text:
00401197callMessageBoxA
为动态提示时察看方便,我们将其导入到ollydbg中。
如图,创建MAP文件。
然后,用ollydbg中的LoadMap插件,将其导入:
动态调试可知
RSA(序列号)除1337=姓名的ASCII码
故序列号=RSA(姓名的ASCII码×1337)
n=0x8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89
e=0x10001
已知n、e,下面计算密钥d
打开RSATOOL2软件:
1―――填入NN=8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89
2―――点FactorN按钮,几分钟后得出P和Q
P=970E1A438A10E069571BDCCBB
Q=EB3FFE9F5C761995147C7A28B
3―――点CalcD按钮,立刻得出d=32593252229255151794D86C1A09C7AFCC2CCE42D440F55A2D
最后,用VisualC++和MIRACL大数库写出注册机。
我写了console版和windows版各一个。
windows版核心代码如下:
mip->IOBASE=16;//16进制模式
c=mirvar(0);//MIRACL的大数类型
n=mirvar(0);
d=mirvar(0);
m=mirvar(0);
mul=mirvar(0x1337);
bytes_to_big(len,szName,c);//将姓名转换成大数
cinstr(n,"8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89");//初始化模数n
cinstr(d,"32593252229255151794D86C1A09C7AFCC2CCE42D440F55A2D");//初始化私钥d
multiply(c,mul,c);//姓名的大数乘以1337
powmod(c,d,n,m);//计算m=(c^d)modn
cotstr(m,szSerial);//将m的16进制串表示写入szSerial中,即为注册码
mirkill(c);
mirkill(n);
mirkill(d);
mirkill(m);
mirkill(mul);
mirexit();
SetDlgItemText(hWnd,IDC_TXT1,szSerial);//显示正确的序列号
附录1如何在VisualC++中使用MIRACL
TocreateMIRACLapplicationsunderMicrosoftWindowsusingMicrosoftC++
version6.0,followthesesteps.Remembera"Release"buildwillbe
fasterthana"Debug"build.ForMSVC++.NETseebelow.
1.Createanewemptyprojectoftype"Win32ConsoleApplication"
Giveitthenameoftheassociatedmainprojectfile,e.g.limlee
forlimlee.cpp
2.Clickon"Project",andthenon"AddtoProject",andthenon"Files"
3.Select"libraryfiles(.lib)"fromthe"Filesoftype"drop-downlist.
LookfortheprecompiledMIRACLlibraryfilems32.lib,andinsertit
intotheproject.
4.Addthemainprojectfile(e.g.limlee.cpp)intotheproject.
5.OnlyifitisaC++mainprojectfile,alsoaddintotheprojectany
otherneededfiles,likebig.cpp/zzn.cppetc.Thoserequiredare
specifiedinthecommentsatthestartofthemainprojectfile,e.g.
*Requires:
big.cppzzn.cpp
ThisstepisnotrequiredforCprojects.
6.Nowclickon"Project"andthenon"Settings".ClicktheC/C++taband
selectthe"preprocessor"category.Findthebox"AdditionalInclude
Directories",andspecifyapathtothemiraclheaderfiles,
mirdef.h/miracl.h/big.hetc..
7.Makesurethatanyfilesneededbytheapplicationareavailableinthe
directoryfromwhichtheapplicationisrun.Forexample*.key*.dss,
or*.ecsfiles
8.Nowbuildandruntheproject.
TocreateanewversionoftheMIRACLlibrary,
1.Compileandruntheconfig.cutility,andrenamethegeneratedmirdef.tst
tomirdef.h
NotethatMicrosoftChasa64-bitintegerdatatypecalled__int64
2.Createanewprojectoftype"Win32StaticLibrary".Thenclickon"Finish".
3.Addintheappropriatefilesmr*.c.Theonesrequiredarethoselistedin
miracl.lst(alsogeneratedbytheconfigutility).
4.Nowclickon"Project"andthenon"Settings".ClicktheC/C++taband
selectthe"preprocessor"category.Findthebox"AdditionalInclude
Directories",andspecifyapathtothemiraclheaderfiles
mirdef.handmiracl.h
5.NowbuildtheprojectandcreatetheMIRACLlibrary.
--------------------------------------------------------------------------------------------
TocreateMIRACLapplicationsunderMicrosoftWindowsusingMicrosoftC++
.NET,followthesesteps.
1.ClickonNewandProject,andselect"VisualC++Projects","Win32",
select"Win32ConsoleProject",andgivetheprojectname,forexample
limlee,forthelimlee.cppexample.ClickonFinish.
2.Nowthingsgetalittletricky.Anemptylimlee.cppfileisprovided.
YoumustnowcutandpastefromtheMiraclprovidedfilelimlee.cppinto
thisone.Notethatthemainprogramisnowcalled_tmain.
3.ClickonProject,andon"AddexistingItem",andSelect"Allfiles"from
the"Filesoftype"drop-downlist.
LookfortheprecompiledMIRACLlibraryfilems32.lib,andinsertit
intotheproject.
4.OnlyifitisaC++mainprojectfile,alsoaddintotheprojectany
otherneededfiles,likebig.cpp/zzn.cppetc.Thoserequiredare
specifiedinthecommentsatthestartofthemainprojectfile,e.g.
*Requires:
big.cppzzn.cpp
ThisstepisnotrequiredforCprojects.Use"Project",and"Addexisting
Item".
5.ClickonProjectandthen"Properties".OpenuptheC++Tab,goto"Precompiled
Headers",andselect"Notusingprecompiledheaders"fromthedrop-downbox.
Openthe"General"Tab,andspecifyapathtothemiraclheaderfiles,mirdef.h,
miracl.handbig.hetc.
6.Buildtheprojectandrunitbyclicking"Debug"and"Start".Theprogramruns
tocompletionandexits.
TocreateanewversionoftheMIRACLlibrary,firstcreateasuitable
mirdef.hasabove,then
1.ClickonNewandProject,andselect"VisualC++Projects","Win32",
enterthenameMiraclandclickon"Win32Project"andthenOK.
2.Clickon"ApplicationSettings",andthenselect"StaticLibrary".
ThenclickonFinish
3.Addintheappropriatefilesmr*.c.(Projectfollowedby"AddExistingItems").
4.ClickonProjectandthen"Properties".OpenuptheC++Tab,goto"Precompiled
Headers",andselect"Notusingprecompiledheaders"fromthedrop-downbox.
Openthe"General"Tab,andspecifyapathtothemiraclheaderfiles,mirdef.h
andmiracl.h
5.Nowbuildtheproject.
--------------------------------------------------------------------------------------
IfusingMIRACLwithinanMFCbasedWin32project,herearesomehints.
1.BuildaMIRACLlibrarywithMR_NO_STANDARD_IOdefinedinmirdef.h
Theconfig.cutilitycanbeusedasusualtocreateasuitablemirdef.h
2.IfusingtheC++MIRACLclasses,don'tforgettochangethedefaultproject
settingsfortheMIRACLimplementationfilessuchasbig.cppto"notusing
pre-compiledheaders".
3.Don'tforgetthatMIRACLisaClibrary,notC++.TocallMIRACLroutines
directlyfromaC++programyoumust:
-
extern"C"
{
#include"miracl.h"
}
IfusingC++,itsprobablypreferabletoaccessMIRACLviatheC++wrapper
classessuchasimplementedbybig.h/big.cpp.Seebig.hfileformoretips.
4.Todisplayabignumber,convertitfirsttoastring.See