记录自己学习RSA所做的一些题。
目录
【RSA1】P1(p,q,e,c)
已知p,q,e,c,可直接求出d,然后求出m
import gmpy2
p = 10554915510546378513140074459658086644656654144905337809416976066414771647836950941616441505897207397834928781511863699153349798682451297889979721668885951
q = 8246403321715011123191410826902524505032643184038566851264109473851746507405534573077909160292816825514872584170252311902322051822644609979417178306809223
e = 65537
c = 40005881669517895877352756665523238535105922590962714344556374248977905431683140065629966778249773228248201807844489945346731806741025157651474530811920115794270396320935022110691338083709019538562205165553541077855422953438117902279834449006455379382431883650004540282758907332683496655914597029545677184720
n = p*q
phi1 = (q-1)*(p-1)
d = gmpy2.invert(e, phi1)
m = gmpy2.powmod(c, d, n)
m = hex(m).replace('0x', '')
flag = bytes.fromhex(m)
print(flag)
【RSA1】P2(n,e,c)
已知n,e,c,在线网站分解n,得到p,q
分解网站:factordb.com
import gmpy2
n = 7382582015733895208810490097582153009797420348201515356767397357174775587237553842395468027650317457503579404097373070312978350435795210286224491315941881
e = 65537
c = 6511001389892474870028836129813814173158254564777610289284056550272120510686249909340499673868720839756059423749304765055919251717618117507007046973023557
# 求出p,q
p = 70538125404512947763739093348083497980212021962975762144416432920656660487657
q = 104660876276442216612517835199819767034152013287345576481899196023866133215633
# 求d
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
# 求m
m = gmpy2.powmod(c, d, n) # 十进制
# 将m转为十六进制,去掉0x
m = hex(m).replace('0x', '')
print(f"m={m}")
# 将m转化为byte
flag = bytes.fromhex(m)
print(flag)
【RSA1】P4 (yafu)
同样已知n,e,c,且p,q相差不大。
p = getPrime(512)
q = gmpy2.next_prime(p)
解题思路:p和q挨的很近(费马分解),最简单就是拿yafu分解。这个算法的原理是p,q是两个素数,而且他们俩在素数序列里面是一前一后的关系。所以把它们俩的乘积开根号得到的结果一定是p,q之间的一个数。那就可以找这一个数的下一个素数(q),再用n/q得到p.
代码:
temp=gmpy2.iroot(n,2)
q=gmpy2.next_prime(temp)
p=n//q
# gmpy2中的iroot函数是专门用来进行大数开根号.
# gmpy2.iroot(n,t),n是大整数,t是要开的次方.
解题脚本:
import gmpy2
n = 115637000420176820831322601039129424406844427046456738651883381559357542765613732363445112111006849040385859313572091386802534464534403117787314180179562651607533039692795522388596550968316951090748054495960090527479954143448774136390568881020918710834542819900918984139672802889774720153267841255456602500057
e = 65537
c = 98161406745910866780822530171878255235776133393411573803496865047700715941955255328757920065032397556905095591171977170479344602512244671081108703687450560269408412671849929423399172588599903975793985819498354819305128607934552101433664794909855378636055525016664559476808490723554481335856183927702549281730
# 求出p,q
temp = gmpy2.iroot(n, 2)[0]
q = gmpy2.next_prime(temp)
p = n//q
# 求d
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
# 求m
m = gmpy2.powmod(c, d, n)
m = hex(m).replace('0x', '')
flag = bytes.fromhex(m)
print(flag)
【RSA1】P5 (yafu)
同P4,直接用yafu分解n
p = getPrime(512)
q = gmpy2.next_prime(p - getPrime(256))
yafu安装可参考:windows下yafu的下载及其安装_yafu-x64.exe_D-R0s1的博客-优快云博客
【RSA1】P6(e,n1,c1,n2,c2)
已知(e,n1,c1,n2,c1),求m
解题思路:两组数中e相同,n,c不同,n1和n2的最大公因数即为p,之后就能求出q、d,继而求出m
import gmpy2
n1 = 143348646254804947818644803938588739009782265465565896704788366218178523508874903492905378927641178487821742289009401873633609987818871281146199303052141439575438691652893995423962176259643151111739185844059243400387734688275416379337335777994990138009973618431459431410429980866760075387393812720247541406893
n2 = 138110854441015362783564250048191029327770295545362614687087481715680856350219966472039006526758450117969049316234863489558254565946242898336924686721846675826468588471046162610143748100096038583426519355288325214365299329095841907207926280081868726568947436076663762493891291276498567791697978693639037765169
e = 65537
c1 = 54957154834913405861345262613986460384513988240935244315981524013378872930144117440787175357956479768211180412158274730449811947349624843965933828130932856052315165316154486515277625404352272475136003785605985702495858150662789554694910771308456687676791434476722168247882078861234982509648037033827107552029
c2 = 122221335585005390437769701090707585780333874638519916373585594040154234166935881089609641995190534396533473702495240511296379249872039728112248708182969185010334637138777948970821974238214641235158623707766980447918480715835847907220219601467702961667091318910582445444058108454023108157805147341928089334736
q = gmpy2.gcd(n1, n2)
# print(q)
p = n1//q
phi = (p-1)*(q-1)
gcd = gmpy2.gcd(phi,e)
#print(gcd)
d1 = gmpy2.invert(e, phi)
m1 =gmpy2.powmod(c1, d1, n1)
#print(m1)
m1=hex(m1).replace('0x','')
flag = bytes.fromhex(m1)
print(flag)
【SRA1】P7(e,p,q,r)
已知(e,p,q,r),求m
from Crypto.Util.number import *
flag = b'NSSCTF{******}' + b'1'*170
p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
n = p*q*r
e = 65537
phi = (p-1)*(q-1)*(r-1)
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'r = {r}')
print(f'e = {e}')
print(f'c = {c}')
脚本:
import gmpy2
p = 10666139331774428325755287635566473140804481321882464031499529816800186578792308674238646794969384836340484775213796013129603472328582005363876462361316357
q = 8419311673449738061914489023962717718536471719688567807316495262754711350004888752049108347226115000749280146228195893953964759818878155006622123533942989
r = 12875078327453384158245832541544758526474680184252540739652077682353277702054275525591573258723948221345537075374635382175740236093131628077747126356403959
e = 65537
c = 424552463648937499189041230155623101311087334789253159440707211761796081289342164253743235182597460622581134089949035117444838205449163269030784233435435681797627188717450074808905561404960693227573181548281296514743775615606388692910356320667720308219275107443303501165027740512539959960217657836317351146520079753390346207659007421416917274795119021374032194294225350901136669304225010974617136606299060486198480556729770211945777266366417547752798441211059402
n = p*q*r
phi = (p-1)*(q-1)*(r-1)
d = gmpy2.invert(e, phi)
m = gmpy2.powmod(c, d, n)
m = hex(m).replace('0x','')
flag = bytes.fromhex(m)
print(flag)
str1 = str(flag)
str2 = ''
for i in str1:
if i != '1':
str2 += i
#print(str2)
str3 = "+b'1'*170"
print(str2+str3)
【RSA1】P8
方法同P7
from Crypto.Util.number import *
flag = b'NSSCTF{******}' + b'1'*100
p = getPrime(256)
q = getPrime(256)
n = (p**3) * q
e = 65537
phi = (p-1)*(q-1)
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'e = {e}')
print(f'c = {c}')
'''
p = 80505091208742938705306670241621545375764148093711243653439069254008824979403
q = 67599990875658931406915486208971556223245451500927259766683936131876689508521
e = 65537
c = 7958690969908064264211283192959937430539613460471121984649054121171267262097603091410178042319139582772142226087020110084551158367679146616732446561228522673699836019156243452069036383047309578614662564794584927846163157472211089368697387945469398750955336949678910159585015004994620777231073804301249774041
'''
脚本:
import gmpy2
p = 80505091208742938705306670241621545375764148093711243653439069254008824979403
q = 67599990875658931406915486208971556223245451500927259766683936131876689508521
e = 65537
c = 7958690969908064264211283192959937430539613460471121984649054121171267262097603091410178042319139582772142226087020110084551158367679146616732446561228522673699836019156243452069036383047309578614662564794584927846163157472211089368697387945469398750955336949678910159585015004994620777231073804301249774041
n = (p**3) * q
#print(n)
phi = (p**3-p**2)*(q-1)
d = gmpy2.invert(e, phi)
m = gmpy2.powmod(c, d, n)
#print(m)
m = hex(m).replace('0x', '')
#print(m)
flag = bytes.fromhex(m)
print(flag)
str1 = str(flag)
str2 = ''
for i in str1:
if i != '1':
str2 += i
print(str2)
str3 = "+b'1'*100"
print(str2+str3)
【RSA1】P9(考虑flag很短)
已知(e,p,q,r),且,求m
from Crypto.Util.number import *
flag = b'NSSCTF{******}'
p = getPrime(512)
q = getPrime(512)
e = 65537
while True:
r = 2*getPrime(100)*e+1
if isPrime(r):
break
n = p*q*r
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'r = {r}')
print(f'e = {e}')
print(f'c = {c}')
'''
p = 7478755670255767435237487693415479182290330775502792675052667363676831056436638619069277770540533350723045234676443621124912287506103439704868369839725279
q = 9232828888049557325429111621080998490274442347556398052322580869768941301413255711626092627273543579067597113958627672298942570149816938335701615759283713
r = 102909133680612532601801231903654039
e = 65537
c = 142893174944324070830219394465469685943669308818639857030565389839224452373848570577201378981080333784852764502832587008270072323948511579823852437852643609820245476634896477031076952735298279618952398460203032125853063235638358942643559551563899381032067185778629120272032518475352761100115057449043142848203976076694124978394099839339406197
'''
解题思路:若用P7的方法解这个题会提示逆元不存在,这是为什么呢?我们来计算一下
,
发现e和phi不互素,不互素则逆元不存在。那么如何解决这个问题呢?可以考虑flag比较短,flag转化为数字m后足够小,则有
也就是说m不仅比n小,还比pq小,所以取模得到的结果也相同。那么此时有,设
即c1为c再模pq的结果,根据模的性质得c1就是使用公钥(pq,e)加密的结果,我们求出该公钥对应的私钥进行解密,得到m mod pq的结果,又因为m比较小,所以该结果就是m.
通俗点的理解就是当m比较小时,就算公钥对应的私钥不存在(逆元不存在) , 我们可以考虑将公钥转化为其他公钥(用原公钥因子进行重组)再尝试求解私钥进行解密,依然可以得到正确结果。
import gmpy2
p = 7478755670255767435237487693415479182290330775502792675052667363676831056436638619069277770540533350723045234676443621124912287506103439704868369839725279
q = 9232828888049557325429111621080998490274442347556398052322580869768941301413255711626092627273543579067597113958627672298942570149816938335701615759283713
r = 102909133680612532601801231903654039
e = 65537
c = 142893174944324070830219394465469685943669308818639857030565389839224452373848570577201378981080333784852764502832587008270072323948511579823852437852643609820245476634896477031076952735298279618952398460203032125853063235638358942643559551563899381032067185778629120272032518475352761100115057449043142848203976076694124978394099839339406197
n = p*q
phi = (p-1)*(q-1)
gcd = gmpy2.gcd(r-1,e)
print(gcd)
d = gmpy2.invert(e, phi)
m = gmpy2.powmod(c, d, n)
print(m)
m = hex(m).replace('0x','')
flag = bytes.fromhex(m)
print(flag)
【RSA1】P10 (e和phi不互素)
已知(e,p,q,c),但是e和phi不互素
from Crypto.Util.number import *
flag = b'NSSCTF{******}'
p = getPrime(512)
q = getPrime(512)
e = 65537*2
n = p*q
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'e = {e}')
print(f'c = {c}')
'''
p = 9927950299160071928293508814174740578824022211226572614475267385787727188317224760986347883270504573953862618573051241506246884352854313099453586586022059
q = 9606476151905841036013578452822151891782938033700390347379468858357928877640534612459734825681004415976431665670102068256547092636766287603818164456689343
e = 131074
c = 68145285629092005589126591120307889109483909395989426479108244531402455690717006058397784318664114589567149811644664654952286387794458474073250495807456996723468838094551501146672038892183058042546944692051403972876692350946611736455784779361761930869993818138259781995078436790236277196516800834433299672560
'''
解题思路:先求出e和phi的最大公约数,(
)和phi互素,然后求出
,继而解出m
import gmpy2
import libnum
p = 9927950299160071928293508814174740578824022211226572614475267385787727188317224760986347883270504573953862618573051241506246884352854313099453586586022059
q = 9606476151905841036013578452822151891782938033700390347379468858357928877640534612459734825681004415976431665670102068256547092636766287603818164456689343
e = 131074
c = 68145285629092005589126591120307889109483909395989426479108244531402455690717006058397784318664114589567149811644664654952286387794458474073250495807456996723468838094551501146672038892183058042546944692051403972876692350946611736455784779361761930869993818138259781995078436790236277196516800834433299672560
n = p*q
phi = (p-1)*(q-1)
gcd1 = gmpy2.gcd(e, phi)
t1 = e//gcd1
dt = gmpy2.invert(t1, phi)
m_gcd1 = gmpy2.powmod(c, dt, n)
m = gmpy2.iroot(m_gcd1, gcd1) # 得到元组 (mpz(1920535408007397829480400151650246901210634018403879187581), True)
flag = libnum.n2s(int(m[0]))
print(flag)
【RSA2】P1(低加密指数)
低加密指数攻击
加密指数指的是e,e一般取65535,但当e很小时,可直接解密
解题思路:RSA加密公式为,
若时,
,所以直接对c开e次方就能得到m
若时,假设
的商为k,则
,对k进行爆破,只要k满足 kn + c能够开e次方就可以得到明文.
from Crypto.Util.number import *
from gmpy2 import *
flag = b'NSSCTF{******}'
p = getPrime(5120)
q = getPrime(5120)
n = p*q
e = 97
phi = (p-1)*(q-1)
m = bytes_to_long(flag)
c = powmod(m, e, n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
'''
n = 1392208858696945158251408085300402884210409327605255122395601049457847957306648819174395014931778575812308192875319127224095733396726388842605854427013313599830150182564652493067830031524869535522568868597852507293377043240832819715539722122306829543983051745406887140154364256267942350230636870212935356815475345989038318923389132101208917912083817520799490534351545373438629367819085151041702754019127891155542476560972125790519584018715794669416759039955180436830478697704458250990786586357019211642837879273967620287257818400267757312623543898635740200839249361087580046496969637043238450499583879116276661827372750638403042213043389905183760455450595752578482968202040860053524276678108325784161897719093223308370971388068813420487879756084379519128232693549989942550047529174783976176943482484756074638704076740157397067892580297182979526978967352014250386678155843772313996171396582929433057131989693861316408604436872931427368192437680361830753162284661119995125858203931094922686321756465463988790748131178263745308042820480140189644732824717255521633534750635979508673908361269979175726073254050574688259969290376926807033728165164896588540691889207252105903436659968119091774687841336252628343233161941187968365128093917171537997137001140227677728923114895809278926486615010954871408034272872411042537353956193868948909981683850857262457369506288525323882308421700421661036191853577105238753230479541719001794464585534292774768292358961920606891227776349593589481547577148801600196035588544512224775960892265021565124673788852875005526313525709353599584812394138968970647681759439523307392275602626903789154682706839530654070108096741181206975334567778238856983205004289416400671597321919876279909765650782227834097342294844294386380646928266942749144240020420237153276705785759403019072953506982997681174635673907151856644499332322321579088035719680421458310273802481031746012298208449699089203065699598926690947025679591160106357130634946357609420125223580319677387654711233585375013067828291928349946599077331636017784447090096340360087970540477975170379810969501197027775838769222713506443846417124839450184827707739588007707714623211453528342755023849716924694572679150284882978804641986457119009272574734697043321033091757474387114449914271460113979531460465175717705674905568446670579332667139075523255580471183372714211547822093365025438653384719374474230360983878837077517864405475258349436531094649276628214288499716485354283135575921258757214288792410583835467572916298688718758374714560819702413058421373661892101033513816116981698045524150518509405086125781764762145577981637953775680403132163846782252745029783387112660812179706752454175492501665442704630131729362621965258498471247871904163412798544329515689112368523703890083138721480476796720323855371775568097188216621368341228806795058046403892301673157631331636430392885315997250027372621883549649614866115616619234953579196607399899485002042456482969222428121605212017146571466818179341621066715472184636758016242256725063854155219754299817717414423725704356940589670902509021070871847017199593680033
e = 97
c = 79418540691422578656139651796213224829563266521211325595707569487401417030874358531413674275017334363641194166574500833916574827523075402219754470871728896772312056257743844227927800121160288525434484105786180547178403828613331285574461293211150728313415280329153597549251599876668080073528625299164784405291297754331374420687599875173508778209038236713812747215157059659564867241144529476211694011692007565732793105429228730285249025627762831080251661835294067942958070742202862164086250986988784472568266652325462247009294865764533077164470382743735937483173523682749295196383707694876943634298051820105410771024861599560176707940488888601355473498847493259474613261665538825299531665650233837474894442826242097663456648233384047622152817959729025415665280499618951478005159820575701483220155180955748454167435711033379910310483689839303198822665341421591234243891877857520663120183063591818656508336831518527692847950877186870610083654117153248336928856886934232488927132245720058243202637258025864487122393335118118013444397135476780564523166548571927547341556616683070253790368891423731046742936358877118104790084195711730135202600692806999992373490439385845158780392894927697171401722699273071306493916233696254958735540772870249139252741670476667099529502282392011715616110876451102234600267482991583515122052976378641894214562203326290939184469206074418127906704847146567350085797480500249400491003993809769407575997740985283755035509654310797061339563655229926356893455738361409861102662109994984398860070584568014471082484198504331014073023689622378943694856212172718725529473812336321642429261822836311084518735006587545920946664595488768239633950124822001162595168106106356115962424210028401369438479550293237915944302351566624339603616714683958384871326105542659559877758488581425288668613061792514360263277530824203967659102107889148367539858141289229124274098921748855341045565232484417195620758495861456624842263649414501657786484816662971421962216348340311859717286253287173293151613310383128702607971580042308515018120559903265609733911340589091613087560931098833849573462572181625894166772788435459280323623477689159384354671220634694792005231505741029567734616435905915192606539962414882105254409847885996949466940350184140166614950171110955365828033747003120697209120916652982201967537088553504504252785632280900095976870510754563400828951684036526240669112248351928072177486091157562600003336544767896806392523395037345770580482363058065676920013089896399387769312374871419827762872050800055872960573607645266626972865053489632548224840580503746879607167797904430560935476705014800973841917939689270919224595772574781478285359220463175042728750523639669204218676238297875644055563803457896409252533724486937378974745777400567080239687055154021761534918106133195512030935957251049812753269173090858930245212145938555697547499155977225759702066548720079477737104010668116693232798415289735481194922014811945312893853446826780868861295203942063380964100360870361328125
'''
脚本:
import gmpy2
import libnum
n = 1392208858696945158251408085300402884210409327605255122395601049457847957306648819174395014931778575812308192875319127224095733396726388842605854427013313599830150182564652493067830031524869535522568868597852507293377043240832819715539722122306829543983051745406887140154364256267942350230636870212935356815475345989038318923389132101208917912083817520799490534351545373438629367819085151041702754019127891155542476560972125790519584018715794669416759039955180436830478697704458250990786586357019211642837879273967620287257818400267757312623543898635740200839249361087580046496969637043238450499583879116276661827372750638403042213043389905183760455450595752578482968202040860053524276678108325784161897719093223308370971388068813420487879756084379519128232693549989942550047529174783976176943482484756074638704076740157397067892580297182979526978967352014250386678155843772313996171396582929433057131989693861316408604436872931427368192437680361830753162284661119995125858203931094922686321756465463988790748131178263745308042820480140189644732824717255521633534750635979508673908361269979175726073254050574688259969290376926807033728165164896588540691889207252105903436659968119091774687841336252628343233161941187968365128093917171537997137001140227677728923114895809278926486615010954871408034272872411042537353956193868948909981683850857262457369506288525323882308421700421661036191853577105238753230479541719001794464585534292774768292358961920606891227776349593589481547577148801600196035588544512224775960892265021565124673788852875005526313525709353599584812394138968970647681759439523307392275602626903789154682706839530654070108096741181206975334567778238856983205004289416400671597321919876279909765650782227834097342294844294386380646928266942749144240020420237153276705785759403019072953506982997681174635673907151856644499332322321579088035719680421458310273802481031746012298208449699089203065699598926690947025679591160106357130634946357609420125223580319677387654711233585375013067828291928349946599077331636017784447090096340360087970540477975170379810969501197027775838769222713506443846417124839450184827707739588007707714623211453528342755023849716924694572679150284882978804641986457119009272574734697043321033091757474387114449914271460113979531460465175717705674905568446670579332667139075523255580471183372714211547822093365025438653384719374474230360983878837077517864405475258349436531094649276628214288499716485354283135575921258757214288792410583835467572916298688718758374714560819702413058421373661892101033513816116981698045524150518509405086125781764762145577981637953775680403132163846782252745029783387112660812179706752454175492501665442704630131729362621965258498471247871904163412798544329515689112368523703890083138721480476796720323855371775568097188216621368341228806795058046403892301673157631331636430392885315997250027372621883549649614866115616619234953579196607399899485002042456482969222428121605212017146571466818179341621066715472184636758016242256725063854155219754299817717414423725704356940589670902509021070871847017199593680033
e = 97
c = 79418540691422578656139651796213224829563266521211325595707569487401417030874358531413674275017334363641194166574500833916574827523075402219754470871728896772312056257743844227927800121160288525434484105786180547178403828613331285574461293211150728313415280329153597549251599876668080073528625299164784405291297754331374420687599875173508778209038236713812747215157059659564867241144529476211694011692007565732793105429228730285249025627762831080251661835294067942958070742202862164086250986988784472568266652325462247009294865764533077164470382743735937483173523682749295196383707694876943634298051820105410771024861599560176707940488888601355473498847493259474613261665538825299531665650233837474894442826242097663456648233384047622152817959729025415665280499618951478005159820575701483220155180955748454167435711033379910310483689839303198822665341421591234243891877857520663120183063591818656508336831518527692847950877186870610083654117153248336928856886934232488927132245720058243202637258025864487122393335118118013444397135476780564523166548571927547341556616683070253790368891423731046742936358877118104790084195711730135202600692806999992373490439385845158780392894927697171401722699273071306493916233696254958735540772870249139252741670476667099529502282392011715616110876451102234600267482991583515122052976378641894214562203326290939184469206074418127906704847146567350085797480500249400491003993809769407575997740985283755035509654310797061339563655229926356893455738361409861102662109994984398860070584568014471082484198504331014073023689622378943694856212172718725529473812336321642429261822836311084518735006587545920946664595488768239633950124822001162595168106106356115962424210028401369438479550293237915944302351566624339603616714683958384871326105542659559877758488581425288668613061792514360263277530824203967659102107889148367539858141289229124274098921748855341045565232484417195620758495861456624842263649414501657786484816662971421962216348340311859717286253287173293151613310383128702607971580042308515018120559903265609733911340589091613087560931098833849573462572181625894166772788435459280323623477689159384354671220634694792005231505741029567734616435905915192606539962414882105254409847885996949466940350184140166614950171110955365828033747003120697209120916652982201967537088553504504252785632280900095976870510754563400828951684036526240669112248351928072177486091157562600003336544767896806392523395037345770580482363058065676920013089896399387769312374871419827762872050800055872960573607645266626972865053489632548224840580503746879607167797904430560935476705014800973841917939689270919224595772574781478285359220463175042728750523639669204218676238297875644055563803457896409252533724486937378974745777400567080239687055154021761534918106133195512030935957251049812753269173090858930245212145938555697547499155977225759702066548720079477737104010668116693232798415289735481194922014811945312893853446826780868861295203942063380964100360870361328125
k = 0
while 1:
s = gmpy2.iroot(c+k*n, e)
if s[1]:
print(libnum.n2s(int(s[0])))
break
k += 1
【RSA2】P3(Rabin)
Rabin加密算法
from Crypto.Util.number import *
from gmpy2 import *
flag = b'NSSCTF{******}'
p = getPrime(256)
q = getPrime(256)
assert p%4 == 3 and q%4 == 3
n = p*q
e = 2
m = bytes_to_long(flag)
c = powmod(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'e = {e}')
print(f'c = {c}')
'''
p = 67711062621608175960173275013534737889372437946924512522469843485353704013203
q = 91200252033239924238625443698357031288749612243099728355449192607988117291739
e = 2
c = 5251890478898826530186837207902117236305266861227697352434308106457554098811792713226801824100629792962861125855696719512180887415808454466978721678349614
'''
解题思路:刚看到这个题目后,e很小,我以为是低加密指数攻击,但e=2,明显e和phi是不互素的,没有想到解决的办法。后来看了大佬的题解后,才知道是Rabin算法.
Rabin算法是一种基于模平方和模平方根的非对称加密算法。
加密时随机取两个大素数p、q,满足,即这两个素数的形式都是4k+3。
加密过程:
解密过程:
运用欧几里得扩展定理(辗转相除法)得到,
这里,a是p模q的逆元,b是q模p的逆元。我们可以举个例子进行验证,
import gmpy2
a = gmpy2.gcdext(3,10) # 欧几里得扩展定理
print(a) # (mpz(1), mpz(-3), mpz(1))
'''a是一个元组,包含三个元素,a[0]是3和10的最大公因数(3,10)=1,
a[1]是3模10的逆元,
a[2]是10模3的逆元
'''
最后运用中国剩余定理进行计算
【精选】信息安全数学基础——中国剩余定理_信息学 中国剩余定理_@小白.的博客-优快云博客
计算Mi模mi的逆元,即。这里就是分别计算q模p的逆元和p模q的逆元。
正确的flag一定是这四个当中的一个。
要了解Rabin加密算法,请看以下链接:Rabin加密算法_rabin算法_Sway_F的博客-优快云博客
import gmpy2
import libnum
from Crypto.Util.number import long_to_bytes
p = 67711062621608175960173275013534737889372437946924512522469843485353704013203
q = 91200252033239924238625443698357031288749612243099728355449192607988117291739
e = 2
c = 5251890478898826530186837207902117236305266861227697352434308106457554098811792713226801824100629792962861125855696719512180887415808454466978721678349614
n = p*q
# Rebin算法
mp = gmpy2.powmod(c, (p+1)//4, p)
mq = gmpy2.powmod(c, (q+1)//4, q)
gcd1, a, b= gmpy2.gcdext(p, q) # 欧几里得扩展a*p+b*q=gcd1
r=(a*p*mq+b*q*mp)%n
r_=n-r
s=(a*p*mq-b*q*mp)%n
s_=n-s
print(f"r={libnum.n2s(int(r))}")
print(f"r_={libnum.n2s(int(r_))}")
print(f"s={libnum.n2s(int(s))}")
print(f"s_={libnum.n2s(int(s_))}")
【RSA2】P4(Weiner)
已知(e,n,c),求m。d很小且e很大,可知是低解密指数攻击(Wiener攻击)。了解维纳攻击,请移步:
RSA--维纳攻击--代码和题目分析_维纳攻击脚本_Emmaaaaaaaaaa的博客-优快云博客
from Crypto.Util.number import *
from gmpy2 import *
flag = b'NSSCTF{******}'
p = getPrime(256)
q = getPrime(256)
n = p*q
d = getPrime(128)
# print(d)
e = inverse(d, (p-1)*(q-1))
m = bytes_to_long(flag)
c = powmod(m, e, n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
'''
n = 6969872410035233098344189258766624225446081814953480897731644163180991292913719910322241873463164232700368119465476508174863062276659958418657253738005689
e = 3331016607237504021038095412236348385663413736904453330557803644384818257225138777641344877202234881627514102078530507171735156112302207979925588113589669
c = 1754994938947260364311041300467524420957926989584983693004487724099773647229373820465164193428679197813476633649362998772470084452129370353136199193923837
'''
解题脚本:
import libnum
from Crypto.Util.number import long_to_bytes
from xenny.ctf.crypto.modern.asymmetric.rsa import wiener
# e很大 wiener攻击
n = 6969872410035233098344189258766624225446081814953480897731644163180991292913719910322241873463164232700368119465476508174863062276659958418657253738005689
e = 3331016607237504021038095412236348385663413736904453330557803644384818257225138777641344877202234881627514102078530507171735156112302207979925588113589669
c = 1754994938947260364311041300467524420957926989584983693004487724099773647229373820465164193428679197813476633649362998772470084452129370353136199193923837
d, p, q = wiener.attack(n, e)
m = pow(c, d, n)
flag = libnum.n2s(int(m))
print(flag)
【RSA2】P6(p-1光滑)
题目
from Crypto.Util.number import *
from random import choice
flag = b'NSSCTF{******}'
def getMyPrime(nbits):
while True:
p = 1
while p.bit_length() <= nbits:
p *= choice(sieve_base)
if isPrime(p + 1):
return p + 1
p = getMyPrime(256)
q = getMyPrime(256)
n = p * q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
'''
n = 53763529836257082401813045869248978487210852880716446938539970599235060144454914000042178896730979463959004404421520555831136502171902051936080825853063287829
e = 65537
c = 50368170865606429432907125510556310647510431461588875539696416879298699197677994843344925466156992948241894107250131926237473102312181031875514294014181272618
'''
要了解P光滑数,参考:RSA p+1或p-1光滑_p+1光滑_Paintrain的博客-优快云博客
脚本
import libnum
from gmpy2 import gcd,powmod
from Crypto.Util.number import long_to_bytes,inverse
# p-1 光滑
N = 53763529836257082401813045869248978487210852880716446938539970599235060144454914000042178896730979463959004404421520555831136502171902051936080825853063287829
e = 65537
c = 50368170865606429432907125510556310647510431461588875539696416879298699197677994843344925466156992948241894107250131926237473102312181031875514294014181272618
a = 2
n = 2
while True:
a = powmod(a, n, N)
res = gcd(a-1, N)
if res != 1 and res != N:
q = N // res
print("p =", res)
print("q =", q)
break
n += 1
p = 27129468931474722768194257677072900116691863938437565023930764029944386941648043
q = 1981739118154369511414154577570801106446227313943655568841825492553695755235903
phi = (p-1)*(q-1)
d = inverse(e, phi)
m = pow(c, d, N)
flag = libnum.n2s(int(m))
print(flag)
【RSA2】P7 (p+1)光滑
题目
from Crypto.Util.number import *
from random import choice
flag = b'NSSCTF{******}'
def getMyPrime(nbits):
while True:
p = 1
while p.bit_length() <= nbits:
p *= choice(sieve_base)
if isPrime(p - 1):
return p - 1
p = getMyPrime(256)
q = getMyPrime(256)
n = p * q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
'''
n = 63398538193562720708999492397588489035970399414238113344990243900620729661046648078623873637152448697806039260616826648343172207246183989202073562200879290937
e = 65537
c = 26971181342240802276810747395669930355754928952080329914687241779532014305320191048439959934699795162709365987652696472998140484810728817991804469778237933925
'''
解题环境:Ubuntu22.04
SageMath version 9.5
安装教程:Ubuntu22.04从下载到正常使用(图文教程),各种问题解决方案。各版本大同小异_强尼.的博客-优快云博客
Ubuntu安装sagemath环境搭建_sagemath 安装_是红衣啊的博客-优快云博客
脚本
from sage.all_cmdline import *
from xenny.ctf.crypto.modern.asymmetric.rsa import williams_pp1
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert,powmod
# p+1光滑
n = 63398538193562720708999492397588489035970399414238113344990243900620729661046648078623873637152448697806039260616826648343172207246183989202073562200879290937
e = 65537
c = 26971181342240802276810747395669930355754928952080329914687241779532014305320191048439959934699795162709365987652696472998140484810728817991804469778237933925
p,q = williams_pp1.attack(n,55)
phi = (p-1)*(q-1)
d = invert(e,phi)
m = powmod(c,d,n)
flag = long_to_bytes(m)
print(flag)
【RSA2】P8 共模攻击
已知(n,e1,e2,c1,c2),求m。
解题思路:此类型题为共模攻击,
当e1,e2互素时,必有(其中a,b必为一正一负)。利用欧几里得扩展算法就能得到a,b的一组解。
题目
from Crypto.Util.number import *
flag = b'NSSCTF{******}'
p = getPrime(512)
q = getPrime(512)
n = p*q
e1 = getPrime(16)
e2 = getPrime(16)
m = bytes_to_long(flag)
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
print(f'n = {n}')
print(f'e1 = {e1}')
print(f'e2 = {e2}')
print(f'c1 = {c1}')
print(f'c2 = {c2}')
'''
n = 120294155186626082670474649118722298040433501930335450479777638508444129059776534554344361441717048531505985491664356283524886091709370969857047470362547600390987665105196367975719516115980157839088766927450099353377496192206005171597109864609567336679138620134544004766539483664270351472198486955623315909571
e1 = 38317
e2 = 63409
c1 = 42703138696187395030337205860503270214353151588149506110731264952595193757235229215067638858431493587093612397165407221394174690263691095324298012134779703041752810028935711214038835584823385108771901216441784673199846041109074467177891680923593206326788523158180637665813642688824593788192044139055552031622
c2 = 50460092786111470408945316270086812807230253234809303694007902628924057713984397041141665125615735752600114964852157684904429928771531639899496987905067366415806771003121954852465731110629459725994454904159277228514337278105207721011579794604761255522391446534458815389983562890631994726687526070228315925638
'''
脚本1
import gmpy2
import libnum
n = 120294155186626082670474649118722298040433501930335450479777638508444129059776534554344361441717048531505985491664356283524886091709370969857047470362547600390987665105196367975719516115980157839088766927450099353377496192206005171597109864609567336679138620134544004766539483664270351472198486955623315909571
e1 = 38317
e2 = 63409
c1 = 42703138696187395030337205860503270214353151588149506110731264952595193757235229215067638858431493587093612397165407221394174690263691095324298012134779703041752810028935711214038835584823385108771901216441784673199846041109074467177891680923593206326788523158180637665813642688824593788192044139055552031622
c2 = 50460092786111470408945316270086812807230253234809303694007902628924057713984397041141665125615735752600114964852157684904429928771531639899496987905067366415806771003121954852465731110629459725994454904159277228514337278105207721011579794604761255522391446534458815389983562890631994726687526070228315925638
s, a, b = gmpy2.gcdext(e1, e2)
m = ((pow(c1, a, n)*pow(c2, b, n))%n)
flag = libnum.n2s(int(m))
print(flag)
脚本2
from Crypto.Util.number import bytes_to_long, long_to_bytes
import gmpy2
n = 120294155186626082670474649118722298040433501930335450479777638508444129059776534554344361441717048531505985491664356283524886091709370969857047470362547600390987665105196367975719516115980157839088766927450099353377496192206005171597109864609567336679138620134544004766539483664270351472198486955623315909571
e1 = 38317
e2 = 63409
c1 = 42703138696187395030337205860503270214353151588149506110731264952595193757235229215067638858431493587093612397165407221394174690263691095324298012134779703041752810028935711214038835584823385108771901216441784673199846041109074467177891680923593206326788523158180637665813642688824593788192044139055552031622
c2 = 50460092786111470408945316270086812807230253234809303694007902628924057713984397041141665125615735752600114964852157684904429928771531639899496987905067366415806771003121954852465731110629459725994454904159277228514337278105207721011579794604761255522391446534458815389983562890631994726687526070228315925638
def RSA_ComModAtk(e1, e2, c1, c2, n):
e1, e2, c1, c2, n = int(e1), int(e2), int(c1), int(c2), int(n)
if gmpy2.gcd(e1,e2) ==1:
s = gmpy2.gcdext(e1, e2) # 扩展欧几里得算法-辗转相除法使得 x*e1+y*e2=1,求出t和z
x = s[1]
y = s[2]
if x < 0:
x = - x # 变指数为正值
c1 = gmpy2.invert(c1, n) # 求c1的逆元
if y < 0:
y = -y # 变指数为正值
c2 = gmpy2.invert(c2, n) # 求c2的逆元
m = (pow(c1, x, n) * pow(c2, y, n)) % n # (c1^x*c2^y)%n=m^e1x*me2y%n=m^(e1x+e2y)%n=m%n=m
return m
else :
return bytes_to_long(b'e1 and e2 are not relatively prime') # e1和e2不互质
result = RSA_ComModAtk(e1, e2, c1, c2, n)
print(long_to_bytes(result))
【RSA2】P9 dp、dq泄露
已知(p,q,c,dp,dq),求m。此类型题为dp,dq泄露
解题思路:
已知
解密
分别模p和模q,得
至此,m也就解出来了。(脚本一)
由,
所以
(脚本二)
题目
from Crypto.Util.number import *
flag = b'NSSCTF{******}'
p = getPrime(512)
q = getPrime(512)
n = p*q
e = getPrime(128)
d = inverse(e, (p-1)*(q-1))
dp = d % (p-1)
dq = d % (q-1)
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'c = {c}')
print(f'dp = {dp}')
print(f'dq = {dq}')
'''
p = 13070310882303377463944295715444821218324151935347454554272870042925400761984585838979931730897626589859098834802923539617244712852188293321626061072925723
q = 10411551818233737389114520103233235272671271111546186997024935593000298916988792710521511848414549553426943998093077337023514210631662189798921671306236009
c = 62492280219693914005334023569480350249964827909276875032578276064973191654731196407886841145547165693859745313398152742796887457192397932684370631253099255490064673499746314452067588181106154875239985334051909867580794242253066085627399488604907196244465911471895118443199543361883148941963668551684228132814
dp = 11568639544706374912496682299967972464196129347160700749666263275305083977187758414725188926013198988871173614336707804756059951725809300386252339177953017
dq = 3455040841431633020487528316853620383411361966784138992524801280785753201070735373348570840039176552952269927122259706586236960440300255065994052962742469
'''
脚本一
import gmpy2
from Crypto.Util.number import *
p = 13070310882303377463944295715444821218324151935347454554272870042925400761984585838979931730897626589859098834802923539617244712852188293321626061072925723
q = 10411551818233737389114520103233235272671271111546186997024935593000298916988792710521511848414549553426943998093077337023514210631662189798921671306236009
c = 62492280219693914005334023569480350249964827909276875032578276064973191654731196407886841145547165693859745313398152742796887457192397932684370631253099255490064673499746314452067588181106154875239985334051909867580794242253066085627399488604907196244465911471895118443199543361883148941963668551684228132814
dp = 11568639544706374912496682299967972464196129347160700749666263275305083977187758414725188926013198988871173614336707804756059951725809300386252339177953017
dq = 3455040841431633020487528316853620383411361966784138992524801280785753201070735373348570840039176552952269927122259706586236960440300255065994052962742469
mp = gmpy2.powmod(c, dp, p)
mq = gmpy2.powmod(c, dq, q)
print(long_to_bytes(mp))
print(long_to_bytes(mq))
脚本二
import gmpy2
from Crypto.Util.number import *
p = 13070310882303377463944295715444821218324151935347454554272870042925400761984585838979931730897626589859098834802923539617244712852188293321626061072925723
q = 10411551818233737389114520103233235272671271111546186997024935593000298916988792710521511848414549553426943998093077337023514210631662189798921671306236009
c = 62492280219693914005334023569480350249964827909276875032578276064973191654731196407886841145547165693859745313398152742796887457192397932684370631253099255490064673499746314452067588181106154875239985334051909867580794242253066085627399488604907196244465911471895118443199543361883148941963668551684228132814
dp = 11568639544706374912496682299967972464196129347160700749666263275305083977187758414725188926013198988871173614336707804756059951725809300386252339177953017
dq = 3455040841431633020487528316853620383411361966784138992524801280785753201070735373348570840039176552952269927122259706586236960440300255065994052962742469
p_ = gmpy2.invert(p,q)
mp = gmpy2.powmod(c, dp, p)
mq = gmpy2.powmod(c, dq, q)
m = ((((mq-mp)*p_)%q)*p + mp)
print(long_to_bytes(m))
【RSA2】P10 dp泄露
已知(n,e,c,dp),求m。
解题思路:
题目
from Crypto.Util.number import *
flag = b'NSSCTF{******}' + b'1'*100
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537
d = inverse(e, (p-1)*(q-1))
dp = d % (p-1)
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'n = {n}')
print(f'c = {c}')
print(f'dp = {dp}')
'''
n = 79201858340517902370077926747686673001645933420450220163567700296597652438275339093680329918615445030212417351430952656177171126427547284822789947152085534939195866096891005587613262293569611913019639653984932469691636338705418303482885987114085769045348074530172292982433373154900841135911548332400167290083
c = 70109332985937768446301118795636999352761371683181615470371772202170324747707233792154935611826981798791499937601162039878070094663516868746240133223110650205575807753345252087103328657073552992431511929172241702073381723302143955977662087561904058172777520360991685289300855900793806183473523998422682944404
dp = 3098334089252415941833934532457314870210700261428241562420857845879512952043729097866485406309479489101668423603305497982177150304625615059119312238777275
'''
脚本:
import gmpy2
import libnum
e = 65537
n = 79201858340517902370077926747686673001645933420450220163567700296597652438275339093680329918615445030212417351430952656177171126427547284822789947152085534939195866096891005587613262293569611913019639653984932469691636338705418303482885987114085769045348074530172292982433373154900841135911548332400167290083
c = 70109332985937768446301118795636999352761371683181615470371772202170324747707233792154935611826981798791499937601162039878070094663516868746240133223110650205575807753345252087103328657073552992431511929172241702073381723302143955977662087561904058172777520360991685289300855900793806183473523998422682944404
dp = 3098334089252415941833934532457314870210700261428241562420857845879512952043729097866485406309479489101668423603305497982177150304625615059119312238777275
for x in range(1, e):
if e*dp%x==1:
p=(e*dp-1)//x + 1
if n%p==0:
break
q=n//p
d=gmpy2.invert(e, (p-1)*(q-1))
m=gmpy2.powmod(c, d, n)
flag = print(libnum.n2s(int(m)))
【RSA2】p11 大指数dp泄露
同样已知(n,e,dp,c),但e很大,求m。
解题环境:Ubuntu22.04
SageMath version 9.5(二者安装教程【RSA2】p7已写)
题目
from Crypto.Util.number import *
flag = b'NSSCTF{******}' + b'1'*80
p = getPrime(512)
q = getPrime(512)
n = p*q
e = getPrime(128)
d = inverse(e, (p-1)*(q-1))
dp = d % (p-1)
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
print(f'dp = {dp}')
'''
n = 108280026722298796068968170303156759745471686664814404724171434502249429011870583595808692893118419248225924869164875379709992190884930717654004006466664403479467573176438601715156464950045121937338569942817256182277141174728470067308962244296992229214749863655518517510026063088263849891990324547823192559069
e = 305691242207901867366357529364270390903
c = 26537258289122728220745496185201994733321402056894636636642710319261241111675937946139938310952968353253866895253865273981912174303818938005932883052177988834834575591342856235464380238486868448329727891268391728758132913642966389278296932186703733187105516710825918064228397602264185334108934765627411913661
dp = 2656631506624565349527023729530989647164022271235521672257622068579788839123502046687139927161669209201953909023994372208117081512139181611949631467292513
'''
脚本
from sage.all_cmdline import *
from Crypto.Util.number import long_to_bytes
from xenny.ctf.crypto.modern.asymmetric.rsa import dpleak
# 大指数dp泄露
n = 108280026722298796068968170303156759745471686664814404724171434502249429011870583595808692893118419248225924869164875379709992190884930717654004006466664403479467573176438601715156464950045121937338569942817256182277141174728470067308962244296992229214749863655518517510026063088263849891990324547823192559069
e = 305691242207901867366357529364270390903
c = 26537258289122728220745496185201994733321402056894636636642710319261241111675937946139938310952968353253866895253865273981912174303818938005932883052177988834834575591342856235464380238486868448329727891268391728758132913642966389278296932186703733187105516710825918064228397602264185334108934765627411913661
dp = 2656631506624565349527023729530989647164022271235521672257622068579788839123502046687139927161669209201953909023994372208117081512139181611949631467292513
m = dpleak.attack(dp,c,e=e,n=n)
flag = long_to_bytes( m )
print(flag)
【RSA2】P12 d泄露
计算 ,选择一个随机数
,
。
为偶数,故
,其中 r为奇数且 t≥1,然后计算
直到
且
.
如果这样的 存在,则其中的因子
,如这样的
不存在,则重新生成随机数
。
题目
from Crypto.Util.number import *
from gmpy2 import *
p = getPrime(512)
q = getPrime(512)
assert p < q
n = p*q
e = 65537
phi = (p-1)*(q-1)
d = invert(e, phi)
print(f'n = {n}')
print(f'd = {d}')
print('flag is NSSCTF{md5(p)}')
'''
n = 113917408220469425995764932761465306974540330325378601642830241920567032775895088098706711486764203845425248022960733155994427766750033219106642310531864450654102562104771892268897793145789045570107312401570269581223945259704851104645493075550316424129401227653740942495625720165869565257394427181127734628103
d = 15762135247924329080208071933121250646888501386858311483546464344350547831176536290630826247188272280853810047335214127264865205744683174860903496832368687060941437002920094364116706593296591581117381565805322046922482804679245558495134876677733584718947309975077159564300049936769192724856722338627154192353
flag is NSSCTF{md5(p)}
'''
脚本1
import random
from hashlib import md5
import gmpy2
n = 113917408220469425995764932761465306974540330325378601642830241920567032775895088098706711486764203845425248022960733155994427766750033219106642310531864450654102562104771892268897793145789045570107312401570269581223945259704851104645493075550316424129401227653740942495625720165869565257394427181127734628103
d = 15762135247924329080208071933121250646888501386858311483546464344350547831176536290630826247188272280853810047335214127264865205744683174860903496832368687060941437002920094364116706593296591581117381565805322046922482804679245558495134876677733584718947309975077159564300049936769192724856722338627154192353
e = 65537
def divide_pq(e, d, n):
k = e*d - 1
while True:
g = random.randint(2, n-1)
t = k
while True:
if t % 2 != 0:
break
t //= 2
x = pow(g, t, n)
if x > 1 and gmpy2.gcd(x-1, n) > 1:
p = gmpy2.gcd(x-1, n)
return (p, n//p)
p, q = divide_pq(e, d, n)
print(p)
print(q)
flag = md5(str(p).encode()).hexdigest()
print("NSSCTF{"+flag+"}")
脚本2
from gmpy2 import *
from hashlib import md5
#d泄露 分解n
n = 113917408220469425995764932761465306974540330325378601642830241920567032775895088098706711486764203845425248022960733155994427766750033219106642310531864450654102562104771892268897793145789045570107312401570269581223945259704851104645493075550316424129401227653740942495625720165869565257394427181127734628103
d = 15762135247924329080208071933121250646888501386858311483546464344350547831176536290630826247188272280853810047335214127264865205744683174860903496832368687060941437002920094364116706593296591581117381565805322046922482804679245558495134876677733584718947309975077159564300049936769192724856722338627154192353
e = 65537
t = e * d - 1
s = 0
while(t % 2 == 0):
t = t // 2
s += 1
# 此时 e * d - 1 = ( 2 ** s ) * t
p = 2
q = 2
for i in range(1,s):
c1 = powmod(2,powmod(2,i,n) * t , n )
c2 = powmod(2,powmod(2,(i-1),n) * t, n )
if(c2 != 1 and c2 != n-1 and c1 == 1 ):
kp = c2 - 1
p = gcd(kp,n)
break
q = n // p
print(p<q) # True
flag = md5(str(p).encode()).hexdigest()
print("NSSCTF{"+flag+"}")
【RSA3】P1(扩展欧几里得)
裴蜀定理,又称贝祖定理。是一个关于最大公约数的定理。其内容定义为:对于不全为零的任意整数 a 和 b,记二者的最大公约数为 g 即 gcd(a,b) = g,则对于任意整数 x 和 y 都一定满足 ax+by 是 g 的倍数。特别地,一定存在整数 x 和 y 的解,使得 ax+by=gcd(a,b) 成立。它的一个重要推论为:a,b互质的充分必要条件是存在整数x,y 使 ax+by=1; 或者说对于方程 ax+by=1 只有整数a和b互质时,方程才有整数解x,y。
题目:
from Crypto.Util.number import *
flag = b'******'
m1 = bytes_to_long(flag[:len(flag)//2])
m2 = bytes_to_long(flag[len(flag)//2:])
assert 18608629446895353521310408885845687520013234781800558*m1-14258810472138345414555137649316815272478951117940067*m2 == 1
脚本:
import gmpy2
from Crypto.Util.number import long_to_bytes
a = 18608629446895353521310408885845687520013234781800558
b = 14258810472138345414555137649316815272478951117940067
g, m1, m2 = gmpy2.gcdext(a, b)
# print(m1,m2)
for i in range(10):
mh = long_to_bytes(m1 + i*b)
if b'NSSCTF' in mh:
ml = long_to_bytes(-m2 + i*a)
print(mh + ml)
break
【RSA3】P2(高次Rabin)
例题:
from Crypto.Util.number import *
from gmpy2 import *
flag = b'NSSCTF{******}'
p = getPrime(256)
q = getPrime(256)
assert p%4 == 3 and q%4 == 3
n = p*q
e = 4
m = bytes_to_long(flag)
c = powmod(m, e, n)
print(f'p = {p}')
print(f'q = {q}')
print(f'e = {e}')
print(f'c = {c}')
'''
p = 59146104467364373868799971411233588834178779836823785905639649355194168174467
q = 78458230412463183024731868185916348923227701568297699614451375213784918571587
e = 4
c = 1203393285445255679455330581174083350744414151272999693874069337386260499408999133487149585390696161509841251500970131235102423165932460197848215104528310
'''
脚本:
from Crypto.Util.number import *
from gmpy2 import *
p = 59146104467364373868799971411233588834178779836823785905639649355194168174467
q = 78458230412463183024731868185916348923227701568297699614451375213784918571587
e = 4
c = 1203393285445255679455330581174083350744414151272999693874069337386260499408999133487149585390696161509841251500970131235102423165932460197848215104528310
n = p*q
cs = [c]
def rabin_decrypt(c,p,q):
mp = pow(c, (p + 1) // 4, p)
mq = pow(c, (q + 1) // 4, q)
yp = inverse(p,q)
yq = inverse(q,p)
r = (yp * p * mq + yq * q * mp) % n
r_ = n - r
s = (yp * p * mq - yq * q * mp) % n
s_ = n - s
return r,r_,s,s_
for i in range(2):
ps = []
for c2 in cs:
r,r_,s,s_ = rabin_decrypt(c2,p,q)
if r not in ps:
ps.append(r)
if r_ not in ps:
ps.append(r_)
if s not in ps:
ps.append(s)
if s_ not in ps:
ps.append(s_)
# print(ps)
cs = ps
for i in range(len(cs)):
print(long_to_bytes(cs[i]))
【RSA3】P3(连分数利用)
例题:
from Crypto.Util.number import *
from gmpy2 import *
flag = b'NSSCTF{******}'
m1 = bytes_to_long(flag[:len(flag)//2])
m2 = bytes_to_long(flag[len(flag)//2:])
p1 = getPrime(1024)
p2 = next_prime(p1)
q1 = getPrime(400)
q2 = getPrime(400)
n1 = p1 * p1 * q1
n2 = p2 * p2 * q2
e1 = getPrime(128)
e2 = getPrime(128)
c1 = pow(m1, e1, n1)
c2 = pow(m2, e2, n2)
print(f'n1 = {n1}')
print(f'e1 = {e1}')
print(f'c1 = {c1}')
print(f'n2 = {n2}')
print(f'e2 = {e2}')
print(f'c2 = {c2}')
'''
n1 = 45965238261145848306223556876775641787109249067253988455950651872774381183888979035386577960806305813634216583223483001245996467366520071511779063266315692543617195166613592991812117446772937889819643718423377609566597230873623011099295202599905646652692946273375405832062164263711151844949794774229886016858313299259387152937467743637367261734624060321171598033647661809876890249035267180368762739600552966699295210431508056693524383116052539072065535970720901196322942269916455391238409489616842687658335666652878840458263998780783865062993401055465701207886230787204008073260653659510197069116237460322442433331870944968133645513020531983926180514313028320422449103156746225574626841023639595418255472716267486241462968101152032898749
e1 = 279586443815379026299414729432860797623
c1 = 11515318475856179010858377918435934663304239594599788732135470038988222237790835017056954077794506499559722814863240838882673078330335616745578747265404229105473136943188301293198548838105990504750972653445744347121859396823995101611868191609259910876207038154174100742978387355304521374228562928260479446249263909934393657537918407756957032700052269827171045167752168509783885071211516601218892308228572735545579606908430615218499620619028799140945676768341492724044499209913045110359935325510223652935426973411960865908064824205626343685369866932545651037748553442488682593143020861196339307665638704485958986411837014559504992818255506454051842453553265179370878637153602580071152915165775491633322055360737581203750897698007951117808
n2 = 25459365600568360055376316722846535809281537088824978187355135247184417413329012865221456308642116409716822227032113740366024809533942721286337697830775221199570509665320400376959076685728357107457862901087218522281771857981155239522807950207375964963527837592797198372303427082343684305143238075402697262610809363109748984974325271762535573995993132076293275456692621516174749076897962348000698039074721998780555541905706268579496243099763776676950336105074846695227221690550755501320117554250942600626927600558489780841103863110357615957088709321079080707735028039675102383525496673233697130053936053431067133520717494376952763684807635780416860233261892013531534059267366382617635000415723745274490604551078385404286689447761642713963
e2 = 249615977162294580923494787210301891647
c2 = 24544357952213952357056140974408354173440635791397720610932999473703241918398814255275362994811954064820912468224131892551724930677715676493892869921426790840199600798807085779112854131346378899855545138289836687048918660685766286852276199524789699567994154833159365800848535248059731927121269157841084905465048764152977389352561685340108834453730139893330210765986258703154334901509553990091592209268471594519326651914685843021165854654380119091009831071244459145750976193183411590207529489774630266528538380011000213950174694472355034075543687572037516433204151217601537869823709241020510051494619335852686100897182065588340025334679570763716458250649152257797833022586793526594784648938165537701256313728194521212887453997160504204832
'''
解题思路:题目给了n1,n2,先用gcd(n1,n2)试一下,发现结果是1,不能用【RSA1】P6来做。
已知n1=p1^2*q1,n2=p2^2*q2,且p1和p2相差不大,但q1和q2的大小不确定。
p1/p2和1很接近,并且小于1,所以n1/n2的结果和q1/q2很接近,并且,可以通过连分数构造出
的连分数数列。
如果某个分数的分子和分母(这里就代表q1和q2)刚好能被n1和n2整除,则就成功分解,分子和分母也就是我们要找的q1和q2,进而求出p1和p2.参考大佬的博客:湖湘杯 2021 Crypto (连分数运用)_2023湖湘杯_Mr_AgNO3的博客-优快云博客
脚本:
from gmpy2 import iroot,invert
from Crypto.Util.number import *
import hashlib
from hashlib import md5,sha256,sha384
from Crypto.Util.number import long_to_bytes,isPrime,inverse,bytes_to_long
from sympy import prevprime,nextprime
def continuedFra(x,y): # x/y计算连分数数列
cf = []
while y != 0:
cf.append(x // y)
x,y = y,x % y
return cf
print(continuedFra(43,19))
def exp(x,y): # 连分数数列转化成分子和分母
cf = continuedFra(x,y)
fz = [cf[0],cf[0] * cf[1] + 1]
fm = [1,cf[1]]
for i in range(2,len(cf)):
z = fz[i - 1] * cf[i] + fz[i - 2]
m = fm[i - 1] * cf[i] + fm[i - 2]
fz.append(z)
fm.append(m)
return fz,fm # fz分子,fm分母
print(exp(43,19))
def get_p_q(x,y):
tem1,tem2 = exp(x,y)
for i in range(2, len(p)):
x_ = p[i]
y_ = q[i]
if (x % x_ == 0 & y % y_ == 0 & x != x_ & y != y_):
return x_, y_
n1 = 45965238261145848306223556876775641787109249067253988455950651872774381183888979035386577960806305813634216583223483001245996467366520071511779063266315692543617195166613592991812117446772937889819643718423377609566597230873623011099295202599905646652692946273375405832062164263711151844949794774229886016858313299259387152937467743637367261734624060321171598033647661809876890249035267180368762739600552966699295210431508056693524383116052539072065535970720901196322942269916455391238409489616842687658335666652878840458263998780783865062993401055465701207886230787204008073260653659510197069116237460322442433331870944968133645513020531983926180514313028320422449103156746225574626841023639595418255472716267486241462968101152032898749
e1 = 279586443815379026299414729432860797623
c1 = 11515318475856179010858377918435934663304239594599788732135470038988222237790835017056954077794506499559722814863240838882673078330335616745578747265404229105473136943188301293198548838105990504750972653445744347121859396823995101611868191609259910876207038154174100742978387355304521374228562928260479446249263909934393657537918407756957032700052269827171045167752168509783885071211516601218892308228572735545579606908430615218499620619028799140945676768341492724044499209913045110359935325510223652935426973411960865908064824205626343685369866932545651037748553442488682593143020861196339307665638704485958986411837014559504992818255506454051842453553265179370878637153602580071152915165775491633322055360737581203750897698007951117808
n2 = 25459365600568360055376316722846535809281537088824978187355135247184417413329012865221456308642116409716822227032113740366024809533942721286337697830775221199570509665320400376959076685728357107457862901087218522281771857981155239522807950207375964963527837592797198372303427082343684305143238075402697262610809363109748984974325271762535573995993132076293275456692621516174749076897962348000698039074721998780555541905706268579496243099763776676950336105074846695227221690550755501320117554250942600626927600558489780841103863110357615957088709321079080707735028039675102383525496673233697130053936053431067133520717494376952763684807635780416860233261892013531534059267366382617635000415723745274490604551078385404286689447761642713963
e2 = 249615977162294580923494787210301891647
c2 = 24544357952213952357056140974408354173440635791397720610932999473703241918398814255275362994811954064820912468224131892551724930677715676493892869921426790840199600798807085779112854131346378899855545138289836687048918660685766286852276199524789699567994154833159365800848535248059731927121269157841084905465048764152977389352561685340108834453730139893330210765986258703154334901509553990091592209268471594519326651914685843021165854654380119091009831071244459145750976193183411590207529489774630266528538380011000213950174694472355034075543687572037516433204151217601537869823709241020510051494619335852686100897182065588340025334679570763716458250649152257797833022586793526594784648938165537701256313728194521212887453997160504204832
p,q = exp(n1,n2)
q1,q2 = get_p_q(n1,n2)
print(q1)
print(q2)
p1 = iroot(n1//q1,2)[0]
p2 = iroot(n2//q2,2)[0]
def solve(p,q,e,c,n):
phi = p*(p-1)*(q-1)
d = inverse(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
return m,flag
flag = b''
flag += solve(p1,q1,e1,c1,n1)[1]
flag += solve(p2,q2,e2,c2,n2)[1]
print(flag)
低加密指数广播攻击
攻防世界 Crypto OldDriver (低加密指数广播攻击)_ChaoYue_miku的博客-优快云博客l
实现低加密指数广播攻击
需要满足以下三个条件:
(1)加密指数e非常小。
(2)同一份明文使用不同的模数n,相同的加密指数e进行多次加密。
(3)攻击者可以得到每一份加密后的密文和对应的模数n、加密指数e。
例题:
from Crypto.Util.number import *
key = b'{******}'
m = bytes_to_long(key)
e=16
def CRT(x,y):
p=getPrime(512)
q=getPrime(512)
c=pow(y,x,p*q)
return c,p*q
c=[]
n=[]
for i in range(8):
x,y=CRT(e,m)
c.append(x)
n.append(y)
print(f'c={c}')
print(f'n={n}')
'''
c=[7983613764326729716195977642822897460019370474201536966646301040989355873295236115842222156380997212046888330473820921348694848713436717060165346978491473160281455379381377613469736708061919502658427626643417708354155576522478231123265822874154044798905380236970460298651084723905375814139320636180750338444,
129012777921235961241065975521230386162728823984022225120450269477550489931569070551991155051252257167769423042043556849947762911402508800169075635054388985910305042598808730655073574859365269412799765292729155964885263032283111902488834235240334934004509709333047405033239295108153676599698985248441209741699,
91910773777607495491920969423265287664228700238743007354561719755032118074245388903849115271142977666341220166968685847151910272500100107420513277550699947456927894120582263234889319725019753273209613155047691123765555364927631016492893196698033586135415871040047521144482215810737441790636430167656086454803,
5027221846664024898168517119422482557743880923055155211651555667430446583491170103464936951529200929900585924820768874549154112731394547986022995134459349799144430846618996763815999455832839518622459789587799129863259277506632039568128690481140497484967454405545910563591589355092120888057400041687711730086,
11730201128672384954456916699612947757445569739246139462291929564983006772788285782225690382275244091862875099273728780513882996133621729962577459204897106543368061593802760714002141664742431096946165298160274734242447524710173423262814762990852704403661286340618700336423691511232266556805344314696606842972,
81287900038895099402799170268896053726273596195156488633536612876106844438602844734342132578744509383831544438498510141562347708534009905564399336319260532277169575944916302039004074676418941120471519594316066449263106866475117838762001071741668673460175061197470711565545629811670702450499467236921317409505,
64416345863027661058875320363314834959939982883147305541535462066061964736027709689999617236793085326065846307929473231566469015859771117055605295789063086519148146817924686030843810636703408313920975967997901202875950441662512120427018670498689643138956980548073385865561088890240386728365481388541310619769,
33069121572938368309297234949373833877336954326268222769856697011458206289852188719694072910549201938361901797702107038330080411371183173555117915714096738468863011673401547933991291305993111731867911983705470143858204625046100607538967422639946245835329061439423511940410264825287038195231686518353583862604]
n=[85879850333661027778379484343032051229093765595673766121039617477257318471257278465337485222600695061332253940305545133734688515701640716010250846383257741117911835732362198229897017049295682890158968803212563361340153028885667015630897828630356152792281112051659310960440173201623016264432798117235932874093,
135096493487231700049245128075142227221217443515325277691605637420863623368137904394327590422621026399136445862314347997955811990155354464479742771883919921469930134618629389534305906712772685724429619443247680713640026524576242391156340008354333361930227832470860860854479951029320855387368370672814824912943,
98251526731917041519492267516219756891382249614927984729295236755371753139670595941431352987895568209738736738118448108482286339466131334632213738032687384385341892562458832061559685141592608733545730204479761379683210863264692696765789375095502200574003927251664297323748811110041605199723215329640342636311,
79536263139627618399930401844231795746218491004450192110711887941056291454700544252468150979982187635759095031842963314234421288721125679453769121627445298912419387943613062950163198441790414931238124907837446931052675489083990572587217505392325461660458702700824157578777253798865848628283086711725624606439,
73905553417659231118287261471920808856807727253962941075212481515441224601752356207379801344272806622263481662268622193849716618594031808100700381641825974078983088770260703321537431781417767380517462994436390113593747857407200308712078473057495281185102036820941209415954461982309365386503494354713397213083,
116063439890372001766679217279571829505787581739763162972452319101741715345040231558957028722361446165947854599188686631731191545147239332034046955511177038897414728155867863155991846766836438497217739138309928733979602147929081685932112836286985969763106901110798858354145845625072856287077030047885935525039,
81334355493488211809777779040324936733050777311900812880490534548744035530671745622315122270791568437701237761649132585063293908363078910366815661931000248884379161176360818206047609073545500784884510075523438384553024920291466393569068158293237651698419647883420863623264155578958939136889470720230928573159,
88915494915977584870133946331143562634077271875058536027105069277751632620246439277007187860725662237210126957072773732669844356998797023675031959539245396070910063063816177585281279498607812350026362366412122495652183805273188133998228669714897354661496543981806407392402202920314489331115886481786467276573]
'''
解题思路
运用中国剩余定理。
设正整数两两互素,对任意整数
, 一次同余方程组
在模N NN意义下存在唯一解,该解可表示为:
其中,,
,
脚本:
import gmpy2
from functools import reduce
from Crypto.Util.number import long_to_bytes
# 中国剩余定理
def CRT(cipher, n):
N = reduce(lambda x, y: x * y, (i for i in n))
result = 0
data = zip(cipher, n)
for ci, ni in data:
Ni = N // ni
di = gmpy2.invert(Ni, ni)
result += ci * Ni * di
return result % N, N
e = 16
c=[7983613764326729716195977642822897460019370474201536966646301040989355873295236115842222156380997212046888330473820921348694848713436717060165346978491473160281455379381377613469736708061919502658427626643417708354155576522478231123265822874154044798905380236970460298651084723905375814139320636180750338444, 129012777921235961241065975521230386162728823984022225120450269477550489931569070551991155051252257167769423042043556849947762911402508800169075635054388985910305042598808730655073574859365269412799765292729155964885263032283111902488834235240334934004509709333047405033239295108153676599698985248441209741699, 91910773777607495491920969423265287664228700238743007354561719755032118074245388903849115271142977666341220166968685847151910272500100107420513277550699947456927894120582263234889319725019753273209613155047691123765555364927631016492893196698033586135415871040047521144482215810737441790636430167656086454803, 5027221846664024898168517119422482557743880923055155211651555667430446583491170103464936951529200929900585924820768874549154112731394547986022995134459349799144430846618996763815999455832839518622459789587799129863259277506632039568128690481140497484967454405545910563591589355092120888057400041687711730086, 11730201128672384954456916699612947757445569739246139462291929564983006772788285782225690382275244091862875099273728780513882996133621729962577459204897106543368061593802760714002141664742431096946165298160274734242447524710173423262814762990852704403661286340618700336423691511232266556805344314696606842972, 81287900038895099402799170268896053726273596195156488633536612876106844438602844734342132578744509383831544438498510141562347708534009905564399336319260532277169575944916302039004074676418941120471519594316066449263106866475117838762001071741668673460175061197470711565545629811670702450499467236921317409505, 64416345863027661058875320363314834959939982883147305541535462066061964736027709689999617236793085326065846307929473231566469015859771117055605295789063086519148146817924686030843810636703408313920975967997901202875950441662512120427018670498689643138956980548073385865561088890240386728365481388541310619769, 33069121572938368309297234949373833877336954326268222769856697011458206289852188719694072910549201938361901797702107038330080411371183173555117915714096738468863011673401547933991291305993111731867911983705470143858204625046100607538967422639946245835329061439423511940410264825287038195231686518353583862604]
n=[85879850333661027778379484343032051229093765595673766121039617477257318471257278465337485222600695061332253940305545133734688515701640716010250846383257741117911835732362198229897017049295682890158968803212563361340153028885667015630897828630356152792281112051659310960440173201623016264432798117235932874093, 135096493487231700049245128075142227221217443515325277691605637420863623368137904394327590422621026399136445862314347997955811990155354464479742771883919921469930134618629389534305906712772685724429619443247680713640026524576242391156340008354333361930227832470860860854479951029320855387368370672814824912943, 98251526731917041519492267516219756891382249614927984729295236755371753139670595941431352987895568209738736738118448108482286339466131334632213738032687384385341892562458832061559685141592608733545730204479761379683210863264692696765789375095502200574003927251664297323748811110041605199723215329640342636311, 79536263139627618399930401844231795746218491004450192110711887941056291454700544252468150979982187635759095031842963314234421288721125679453769121627445298912419387943613062950163198441790414931238124907837446931052675489083990572587217505392325461660458702700824157578777253798865848628283086711725624606439, 73905553417659231118287261471920808856807727253962941075212481515441224601752356207379801344272806622263481662268622193849716618594031808100700381641825974078983088770260703321537431781417767380517462994436390113593747857407200308712078473057495281185102036820941209415954461982309365386503494354713397213083, 116063439890372001766679217279571829505787581739763162972452319101741715345040231558957028722361446165947854599188686631731191545147239332034046955511177038897414728155867863155991846766836438497217739138309928733979602147929081685932112836286985969763106901110798858354145845625072856287077030047885935525039, 81334355493488211809777779040324936733050777311900812880490534548744035530671745622315122270791568437701237761649132585063293908363078910366815661931000248884379161176360818206047609073545500784884510075523438384553024920291466393569068158293237651698419647883420863623264155578958939136889470720230928573159, 88915494915977584870133946331143562634077271875058536027105069277751632620246439277007187860725662237210126957072773732669844356998797023675031959539245396070910063063816177585281279498607812350026362366412122495652183805273188133998228669714897354661496543981806407392402202920314489331115886481786467276573]
x, N = CRT(c, n)
m = gmpy2.iroot(gmpy2.mpz(x), e)[0]
print(m)
print(long_to_bytes(m))