CTF中关于RSA的常见题型

CTF中关于RSA的常见题型

关RSA算法原理的描述请看https://blog.csdn.net/weixin_43790779/article/details/105622327

1.已知(p, q, e),求d。

示例:【CTF秀-crypto4】 p=447685307 q=2037 e=17,提交flag{d}即可。
解题思路:

import gmpy2
p = 447685307
q = 2037
e = 17
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
print(d)

2.已知(p, q, e,c),求m。

示例:【CTF秀-crypto5】 p=447685307 q=2037 e=17 c=704796792,提交flag{m}。
解题思路:

import gmpy2
p=447685307
q=2037
e=17
c=704796792

phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,p*q)

print(m)

3.已知(p, q, dp,dq,c),求m。

示例:【BUUCTF-RSA1】
解题思路:
m = c d    m o d    n m = c^d \ \ mod\ \ n m=cd  mod  n
n = p ∗ q n = p*q n=pq
d p ≡ d    m o d    ( p − 1 )    ① dp ≡ d \ \ mod\ \ (p-1) \ \ ① dpd  mod  (p1)  
d q ≡ d    m o d    ( q − 1 )    ② dq ≡ d \ \ mod\ \ (q-1) \ \ ② dqd  mod  (q1)  
m p ≡ c d    m o d    p    ③ mp ≡ c^d \ \ mod\ \ p \ \ ③ mpcd  mod  p  
m q ≡ c d    m o d    q    ④ mq ≡ c^d \ \ mod\ \ q \ \ ④ mqcd  mod  q  

由③得, c d = k ∗ p + m p    ⑤ c^d=k*p+mp\ \ ⑤ cd=kp+mp  
将⑤代入④得, k ∗ p ≡ m p − m q    m o d    q k*p≡mp-mq \ \ mod\ \ q kpmpmq  mod  q
k ≡ p − 1 ∗ ( m p − m q )    m o d    q    ⑥ k≡p^{-1}*(mp-mq) \ \ mod\ \ q \ \ ⑥ kp1(mpmq)  mod  q  
将⑥代入⑤得, c d = [ p − 1 ∗ ( m p − m q )    m o d    q ] ∗ p + m p c^d=[p^{-1}*(mp-mq) \ \ mod\ \ q]*p+mp cd=[p1(mpmq)  mod  q]p+mp
由①,②可得, d = d p + k 1 ∗ ( p − 1 ) = d q + k 2 ∗ ( q − 1 ) d=dp+k_1*(p-1)=dq+k_2*(q-1) d=dp+k1(p1)=dq+k2(q1)
由费马小定理可知,
m p ≡ c d    m o d    p ≡ c d p + k 1 ∗ ( p − 1 )    m o d    p ≡ c d p    m o d    p mp ≡c^d \ \ mod\ \ p≡c^{dp+k_1*(p-1)} \ \ mod\ \ p≡c^{dp} \ \ mod\ \ p mpcd  mod  pcdp+k1(p1)  mod  pcdp  mod  p
m q ≡ c d    m o d    q ≡ c d q + k 2 ∗ ( q − 1 )    m o d    q ≡ c d q    m o d    q mq ≡c^d \ \ mod\ \ q≡c^{dq+k_2*(q-1)} \ \ mod\ \ q≡c^{dq} \ \ mod\ \ q mqcd  mod  qcdq+k2(q1)  mod  qcdq  mod  q
m ≡ c d = [ p − 1 ∗ ( c d p    m o d    p − c d q    m o d    q ) ]    m o d    q ∗ p + m p m≡c^d=[p^{-1}*(c^{dp} \ \ mod\ \ p-c^{dq} \ \ mod\ \ q)] \ \ mod\ \ q*p+mp mcd=[p1(cdp  mod  pcdq  mod  q)]  mod  qp+mp

脚本代码如下:

p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229 
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469 
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929 
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041 
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852

import gmpy2
import binascii
I = gmpy2.invert(p,q)
mp = gmpy2.powmod(c,dp,p)
mq = gmpy2.powmod(c,dq,q)

m = ((I*(mp-mq))%q)*p+mp
print(binascii.unhexlify(hex(m)[2:]))

4.已知(e,dp, n, c),求m。

示例:【BUUCTF-RSA2】
解题思路:
e ∗ d ≡ 1    m o d    ( p − 1 ) ( q − 1 ) e*d≡1\ \ mod\ \ (p-1)(q-1) ed1  mod  (p1)(q1)
d p ≡ d    m o d    ( p − 1 )   = = >    e ∗ d p ≡ e ∗ d    m o d    ( p − 1 ) dp≡d\ \ mod\ \ (p-1)\ ==> \ \ e*dp≡e*d\ \ mod\ \ (p-1) dpd  mod  (p1) ==>  edped  mod  (p1)
e ∗ d = k 1 ( p − 1 ) ( q − 1 ) + 1 = k 2 ( p − 1 ) + e ∗ d p e*d=k_1(p-1)(q-1)+1=k_2(p-1)+e*dp ed=k1(p1)(q1)+1=k2(p1)+edp
e ∗ d p = ( p − 1 ) ( k 1 ( q − 1 ) − k 2 ) + 1 e*dp=(p-1)(k_1(q-1)-k_2)+1 edp=(p1)(k1(q1)k2)+1,
因为dp e > ( k 1 ( q − 1 ) − k 2 ) e>(k_1(q-1)-k_2) e>(k1(q1)k2)
( k 1 ( q − 1 ) − k 2 ) ∈ ( 1 , e ) (k_1(q-1)-k_2)∈(1,e) (k1(q1)k2)(1,e),遍历即可求得p的值。

脚本代码如下:

import gmpy2
import binascii
e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751

for i in range(1,e):
    if (e*dp-1)%i == 0 and n%((e*dp-1)//i+1)==0:
        q = n//((e*dp-1)//i+1)
        phi = (q-1)*((e*dp-1)//i)
        d = gmpy2.invert(e,phi)
        m = gmpy2.powmod(c,d,n)

print(binascii.unhexlify(hex(m)[2:]))

5.已知(n, e1, e2,c1,c2),求m。

示例:【BUUCTF-RSA3】
解题思路: 涉及知识点为共模攻击
c 1 ≡ m e 1    m o d    n c1≡m^{e1}\ \ mod\ \ n c1me1  mod  n
c 2 ≡ m e 2    m o d    n c2≡m^{e2}\ \ mod\ \ n c2me2  mod  n
当e1,e2互质时,有ae1+be2=1(其中a,b必为一正一负)。
利用扩展欧几里得算法可求得(a,b)的一组解。

c 1 a ∗ c 2 b    m o d    n c1^a * c2^b\ \ mod\ \ n c1ac2b  mod  n
= ( ( m e 1    m o d    n ) a ∗ ( m e 2    m o d    n ) b )    m o d    n =((m^{e1}\ \ mod\ \ n)^a * (m^{e2}\ \ mod\ \ n)^b)\ \ mod\ \ n =((me1  mod  n)a(me2  mod  n)b)  mod  n
= m a ∗ e 1 + b ∗ e 2    m o d    n , =m^{a*e1+b*e2}\ \ mod\ \ n, =mae1+be2  mod  n,
因为 a ∗ e 1 + b ∗ e 2 = 1 a*e1+b*e2=1 ae1+be2=1,所以
m ≡ c 1 a ∗ c 2 b    m o d    n m≡c1^a * c2^b\ \ mod\ \ n mc1ac2b  mod  n

脚本代码如下:

import gmpy2
import binascii

n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e1 = 11187289
e2 = 9647291

s = gmpy2.gcdext(e1,e2)
a = s[1]
b = s[2]

if a<0:
    a = -a
    c1 = gmpy2.invert(c1,n)
else:
    b = -b
    c2 = gmpy2.invert(c2,n)

m = (gmpy2.powmod(c1,a,n)*gmpy2.powmod(c2,b,n))%n

print(binascii.unhexlify(hex(m)[2:]))

6.已知( e,n1,c1,n2,c2),求m。

示例:【CTF秀-easyrsa2】
解题思路: 两组数中e相同,n,c不同,求出n1与n2的最大公因数即为p,之后就可以得到q和d,从而求解m。

import gmpy2
import binascii

e = 65537
n1 = 23686563925537577753047229040754282953352221724154495390687358877775380147605152455537988563490716943872517593212858326146811511103311865753018329109314623702207073882884251372553225986112006827111351501044972239272200616871716325265416115038890805114829315111950319183189591283821793237999044427887934536835813526748759612963103377803089900662509399569819785571492828112437312659229879806168758843603248823629821851053775458651933952183988482163950039248487270453888288427540305542824179951734412044985364866532124803746008139763081886781361488304666575456680411806505094963425401175510416864929601220556158569443747
c1 = 1627484142237897613944607828268981193911417408064824540711945192035649088104133038147400224070588410335190662682231189997580084680424209495303078061205122848904648319219646588720994019249279863462981015329483724747823991513714172478886306703290044871781158393304147301058706003793357846922086994952763485999282741595204008663847963539422096343391464527068599046946279309037212859931303335507455146001390326550668531665493245293839009832468668390820282664984066399051403227990068032226382222173478078505888238749583237980643698405005689247922901342204142833875409505180847943212126302482358445768662608278731750064815

n2 = 22257605320525584078180889073523223973924192984353847137164605186956629675938929585386392327672065524338176402496414014083816446508860530887742583338880317478862512306633061601510404960095143941320847160562050524072860211772522478494742213643890027443992183362678970426046765630946644339093149139143388752794932806956589884503569175226850419271095336798456238899009883100793515744579945854481430194879360765346236418019384644095257242811629393164402498261066077339304875212250897918420427814000142751282805980632089867108525335488018940091698609890995252413007073725850396076272027183422297684667565712022199054289711
c2 = 2742600695441836559469553702831098375948641915409106976157840377978123912007398753623461112659796209918866985480471911393362797753624479537646802510420415039461832118018849030580675249817576926858363541683135777239322002741820145944286109172066259843766755795255913189902403644721138554935991439893850589677849639263080528599197595705927535430942463184891689410078059090474682694886420022230657661157993875931600932763824618773420077273617106297660195179922018875399174346863404710420166497017196424586116535915712965147141775026549870636328195690774259990189286665844641289108474834973710730426105047318959307995062

p = gmpy2.gcd(n1,n2)
q = n1 // p
phi = (p-1)*(q-1)

d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c1,d,n1)

print(binascii.unhexlify(hex(m)[2:]))

7.已知(p+q,p-q, e,c),求m。

示例:[BJDCTF 2nd]rsa0
解题思路:

import gmpy2
import libnum
e=16300321

a=21350430512059560135536506725886192791652921782342757815537127809818896096167861777432862988721624947176730121127946250044713187944377040826978092675745896

b=1553262765888789433201396543987134442184487100865056152409628170591088051337453032936901834118611146414395714768350794090251064953913440485676167006809370

c=54505145716437017236783669089525458569996474667747952435007039609752579283598944353442923680602360632342975079757448484712025793719352475806343163818881133707590318426509468029706897810742965068881431810720947035196632950024324040788801133194474150406380691624739115334015886740557921339305357167098392744905

p = (a+b)//2
q = (a-b)//2

phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)

m = gmpy2.powmod(c,d,p*q)
print(libnum.n2s(m))

7.已知(e,n,c),求m。

示例:【CTF秀-easyrsa1】
解题思路:
可以分解n得到p,q,在线分解大整数网址http://www.factordb.com/index.php 。

脚本代码如下:

import gmpy2
import binascii

e = 65537
n = 1455925529734358105461406532259911790807347616464991065301847
c = 69380371057914246192606760686152233225659503366319332065009
p = 1201147059438530786835365194567
q = 1212112637077862917192191913841

phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,n)

print(binascii.unhexlify(hex(m)[2:]))

8.已知(e,n,c),求m。(低加密指数攻击)

示例:【CTF秀-easyrsa4】
解题思路: 题中e=3相对于n,c来说极小,故可知是低加密指数攻击
当 m 3 < n 时 , c = m 3 , 直 接 将 c 开 三 次 方 即 可 得 到 m ; 当m^3m3<nc=m3cm
当 m 3 > n 时 , c = m 3 − i ∗ n , 只 要 找 到 i , 使 得 c + i n 能 够 开 三 次 方 即 可 得 到 m 。 当m^3>n时,c = m^3-i *n,只要找到i,使得c+in能够开三次方即可得到m。 m3>nc=m3ini使c+inm

脚本代码如下:

import gmpy2
import binascii

e = 3
n = 18970053728616609366458286067731288749022264959158403758357985915393383117963693827568809925770679353765624810804904382278845526498981422346319417938434861558291366738542079165169736232558687821709937346503480756281489775859439254614472425017554051177725143068122185961552670646275229009531528678548251873421076691650827507829859299300272683223959267661288601619845954466365134077547699819734465321345758416957265682175864227273506250707311775797983409090702086309946790711995796789417222274776215167450093735639202974148778183667502150202265175471213833685988445568819612085268917780718945472573765365588163945754761
c = 150409620528139732054476072280993764527079006992643377862720337847060335153837950368208902491767027770946661

i = 0
while True:
    if gmpy2.iroot((c+i*n),3)[1] == True:
        m = gmpy2.iroot((c+i*n),3)[0]
        break
    i += 1

print(binascii.unhexlify(hex(m)[2:]))

9.已知(e,n,c),求m。(低解密指数攻击)

示例:【CTF秀-easyrsa5】
解题思路: 题中e很大,故可知是低解密指数攻击
可以使用破解脚本:求出d的值,文件下载地址https://github.com/pablocelayes/rsa-wiener-attack
(注意,这里要将破解脚本和rsa-wiener-attack的py文件放在同一个目录下)

脚本代码如下:

import gmpy2
import binascii
import RSAwienerHacker

e = 284100478693161642327695712452505468891794410301906465434604643365855064101922252698327584524956955373553355814138784402605517536436009073372339264422522610010012877243630454889127160056358637599704871937659443985644871453345576728414422489075791739731547285138648307770775155312545928721094602949588237119345
n = 468459887279781789188886188573017406548524570309663876064881031936564733341508945283407498306248145591559137207097347130203582813352382018491852922849186827279111555223982032271701972642438224730082216672110316142528108239708171781850491578433309964093293907697072741538649347894863899103340030347858867705231
c = 350429162418561525458539070186062788413426454598897326594935655762503536409897624028778814302849485850451243934994919418665502401195173255808119461832488053305530748068788500746791135053620550583421369214031040191188956888321397450005528879987036183922578645840167009612661903399312419253694928377398939392827

d = RSAwienerHacker.hack_RSA(e,n)
m = gmpy2.powmod(c,d,n)

print(binascii.unhexlify(hex(m)[2:]))

你可能感兴趣的:(CTF,课程复习,密码学,信息安全)