密码学笔记 Crypto Triode的RSA学习笔记(1) Triode_Lzx 2023-11-17 2023-11-17 在进行RSA解密之前,我们先要理解RSA的加密原理:
已知明文,公钥对,加密过程如下:
若要对已知的密文进行解密,我们就需要得到私钥(Private Key):
设对于上述加密过程所得出的私钥为,则:
很明显:
所以:
一般情况下,,故先对这种情况进行考虑
由欧拉定理:我们知道
很显然:
可以看出:
所以:
已知n,e,c在一般情况下(n可通过软件进行质因数分解)的解密 此时,我们有:
此时,由欧拉函数的性质,我们有:
由欧拉函数的计算公式我们可以知道:
所以对于,有:
特别的,对于质数,有:
若为个不相同质数相乘,即:
有:
在一般情况下只有两个质因数和,例如下题:
1 2 3 4 5 6 7 8 9 10 11 12 13 from Crypto.Util.number import getPrime,bytes_to_long,long_to_bytesfrom gmpy2 import gcd,invertfrom secret import flagm=bytes_to_long(flag) p=274327862430236019688316864082249987313 q=206961224895267889099693426679050192439 n=p*q phi=(p-1 )*(q-1 ) e=65537 c=pow (m,e,n) print ("c =" ,c)
这题直接给出了和,故我们只需要写出如下代码即可解决:
1 2 3 4 5 6 7 8 9 10 11 from Crypto.Util.number import *import gmpy2p = 274327862430236019688316864082249987313 q = 206961224895267889099693426679050192439 c = 54831930044859946955044417597501651143196043923856762253170140444376354297816 e = 65537 n = p * q phi = (p-1 ) * (q-1 ) d = gmpy2.invert(e,phi) m = gmpy2.powmod(c,d,n) print (long_to_bytes(m))
运行即可得出flag:
1 flag{how_excellent_you_are!}
这就是最基本的RSA类型了。
在已知e以及e组(n,c)的广播攻击 此类型攻击属于CRT(Chinese remainder theorem,中国剩余定理,又称孙子定理)类型。
原理不赘述,实质上即为已知组时利用CRT在不对任何一个进行分解的情况下求解明文
在这里,我们设明文为,有:
再通过CRT求解出后对其开次方根即可得到明文
例题 [鹤城杯 2021]Crazy_Rsa_Tech 题目代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from Crypto.Util.number import *from Crypto.Util.Padding import *FLAG = bytes_to_long(pad(b"flag{??????}" ,64 )) def init_key (): p, q = getPrime(512 ), getPrime(512 ) n = p*q e = 9 while (GCD((p-1 )*(q-1 ),e)!=1 ): p, q = getPrime(512 ), getPrime(512 ) n = p*q d = inverse(e,(p-1 )*(q-1 )) return n,e,d n_list=list () c_list=list () for i in range (9 ): N,e,d=init_key() n_list.append(N) c=pow (FLAG,e,N) c_list.append(pow (FLAG,e,N)) assert (pow (c,d,N)==FLAG) print ("n_list:" ,n_list)print ("c_list:" ,c_list)
这里很容易可以知道(显而易见,和也有九组),所以很显然,这题要用到的广播攻击
将上面给出的n_list和c_list用sagemath利用CRT求解得出:
1 m9=3678337284039442047026947312380394506988284605153398380909870598085147736828709178219597429308046538374273111663234962853201175297522552444068549756304348183089003998584929250444862897734669616839072634559776823068102560978738392642133409979083241310818961120830565330801827594023873873703163937572703881578432281109467318674533265052430906776650900523035132668203491899352234368836316318216812572637893433384928785981896373747430646617935503364537613820302679656375356094380483213814869276308187497478084540603362678580814022322799191778371368875742773945120383365613028633102737056410926701477700008313642639347163933146129361496566648131161287075292980980083166106192999528561889437021539352391671756010617540361596164032486633114877739259434431765044242037641759566659268290619705700083536966807192023377334915872207418596226819579720241509860110741821630775501873143209229299530346706612248414951753383716954165108266753409813119293227854442685830689203424064786691447734948037502729127922328149002842971722645909768174575776908113523451541199095073733017029558396658874593357205426105429760517295964966905772455366037986657671195106462661190327510507460112791663031458690187525393979689469548319821181450874331998372947479866557921497942728807505035932385939931524294822439633516457845581452433022749099648076725811489217888688273759202726271093237450290814247396662589614216704
再对开9次方根可得:
1 m=5364346700993245916083351542951836466599376039702798829478182513243184146028312538778801523615449405915572188751896617305936540801999004614344621214275094
再通过Crypto库中long_to_bytes函数可得:
1 flag{H0w_Fun_13_HAstads_broadca5t_AtTack!}
gcd类型 这种类型主要考察数学推导的能力,直接上例题。
[GKCTF 2021]RRRRsa 1(部分) 题目代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 pbits = 512 p, q = getPrime(pbits), getPrime(pbits) n = p * q hint1 = pow (2020 * p + q, 202020 , n) hint2 = pow (2121 * p + 212121 , q, n) print (f'{n = } ' )print (f'{hint1 = } ' )print (f'{hint2 = } ' )""" n = 72480597722768310802103225074022304502987810353239303491995392556828592827312126864102279719480413772239054950810362120660174703790228376146053986053171930937388580526219104498648291397309599209554202670080978901954049943834889894306222459711036629282482760872552358198065124168348275611897584923869319730917 hint1 = 70685159982753618117937078087626553902610663214529331305611406765104333038200912863267956767277081926123480288270862897047313253820275507292683667878994502600957911694615683337770022569861106230373836250952155917286151237134316356851059293688768775787985566372022900108303136666429150678266857778726967849907 hint2 = 59397395285145715354919882069200896861665631746130494855994590508589325004636436593048816842106180115714527211321251497281171549276111388361451000025849056493942252398618018816656979043710894623882099581494083699322411790446784391932055982624616996747139852037848608960801937270797966812928286289985647495610 """
我们可以知道:
我们要从上面两个方程中求解和,下面进行数学推导:
首先观察hint1,由二项式定理有:
显然的,右式除与两项外均能被整除
所以有:
进一步的,有:
现在看到hint2,有:
由费马小定理,可以得到:
所以:
对于hint1:
故:
所以有:
由于
所以
代码如下:
1 2 3 4 5 6 7 8 from Crypto.Util.number import *import gmpy2n = 72480597722768310802103225074022304502987810353239303491995392556828592827312126864102279719480413772239054950810362120660174703790228376146053986053171930937388580526219104498648291397309599209554202670080978901954049943834889894306222459711036629282482760872552358198065124168348275611897584923869319730917 hint1 = 70685159982753618117937078087626553902610663214529331305611406765104333038200912863267956767277081926123480288270862897047313253820275507292683667878994502600957911694615683337770022569861106230373836250952155917286151237134316356851059293688768775787985566372022900108303136666429150678266857778726967849907 hint2 = 59397395285145715354919882069200896861665631746130494855994590508589325004636436593048816842106180115714527211321251497281171549276111388361451000025849056493942252398618018816656979043710894623882099581494083699322411790446784391932055982624616996747139852037848608960801937270797966812928286289985647495610 kq = gmpy2.powmod(2121 ,202020 ,n)*hint1-gmpy2.powmod((hint2-212121 )*2020 ,202020 ,n) q = gmpy2.gcd(kq,n) print (q)
这样就得出了,由此我们就可以顺带求出了。
(还有道题是Geek Challenge 2023的Poly_RSA,但是在写笔记的时候比赛还没结束,就不放出来了,后面写wp的时候再讲推导过程)