import gmpy2 from Crypto.Util.number import * defde(c, e, n): k = 0 whileTrue: m = c + n*k result, flag = gmpy2.iroot(m, e) ifTrue == flag: return result k += 1 e= 3 n= 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793 c= 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365 m=de(c,e,n) print(m) print(long_to_bytes(m))
import gmpy2 import libnum from Crypto.Util.number import long_to_bytes n1 = 20474918894051778533305262345601880928088284471121823754049725354072477155873778848055073843345820697886641086842612486541250183965966001591342031562953561793332341641334302847996108417466360688139866505179689516589305636902137210185624650854906780037204412206309949199080005576922775773722438863762117750429327585792093447423980002401200613302943834212820909269713876683465817369158585822294675056978970612202885426436071950214538262921077409076160417436699836138801162621314845608796870206834704116707763169847387223307828908570944984416973019427529790029089766264949078038669523465243837675263858062854739083634207 c1 = 974463908243330865728978769213595400782053398596897741316275722596415018912929508637393850919224969271766388710025195039896961956062895570062146947736340342927974992616678893372744261954172873490878805483241196345881721164078651156067119957816422768524442025688079462656755605982104174001635345874022133045402344010045961111720151990412034477755851802769069309069018738541854130183692204758761427121279982002993939745343695671900015296790637464880337375511536424796890996526681200633086841036320395847725935744757993013352804650575068136129295591306569213300156333650910795946800820067494143364885842896291126137320 #...此处省略20组n和c e = 65537 n=[] c=[] p=[] for i in range(1,20): n.append(eval('n'+str(i))) c.append(eval('c'+str(i))) data=list(zip(n,c)) for i in range(len(n)): for j in range(i+1,len(n)): if gmpy2.gcd(n[i],n[j])!=1: print(i,j)#i=4,j=17 print(gmpy2.gcd(n[i],n[j])) p=gmpy2.gcd(n5,n18) q=n5//p d = gmpy2.invert(e, (p-1)*(q-1)) print(d) m = pow(c5,d,n5) print(long_to_bytes(m))
思路四、低解密指数攻击(e很大) 适用情况:e很大
和低加密指数攻击相反,当e很大的时候我们怎么办呢,这里就要用到低解密指数攻击。当e很大时,相对的d就会很小。这里我们用到github上一个wienerHacker脚本pablocelayes/rsa-wiener-attack: A Python implementation of the Wiener attack on RSA public-key encryption scheme. (github.com)
下载之后把里面RSAwienerHacker.py改一改输入题目给你的e和n就可以帮你解出d。
例题:BUUCTF RSA2 题目给的e非常大,我们放到脚本里解出d:
有了d后续进行一些转换就很简单了,解密脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12
#低解密指数攻击,使用 RSAwienerHacker脚本解出d #注意python2和python3在hex转换时数据结尾相差差一个L字符,会导致hash值不一样 N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471 e = 46731919563265721307105180410302518676676135509737992912625092976849075262192092549323082367518264378630543338219025744820916471913696072050291990620486581719410354385121760761374229374847695148230596005409978383369740305816082770283909611956355972181848077519920922059268376958811713365106925235218265173085 d = 8920758995414587152829426558580025657357328745839747693739591820283538307445 dd = hex(d) dd = dd+"L" print(dd) import hashlib flag = "flag{" + hashlib.md5(dd.encode("utf-8")).hexdigest() + "}" print(flag)
import gmpy2 from Crypto.Util.number import long_to_bytes e = 65537 n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113 dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657 c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751 for i in range(1, e): if (dp * e - 1) % i == 0: if n % (((dp * e - 1) // i) + 1) == 0: p = ((dp * e - 1) // i) + 1 q = n // (((dp * e - 1) // i) + 1) d = gmpy2.invert(e, (p-1)*(q-1)) m = pow(c, d, n) print(m) print(long_to_bytes(m))
思路七、dp,dq泄露
适用情况:dp,dq同时泄露
有的时候题目把dpdq都给我们了,这个时候我们不用知道e也可以解密。
此时有:
1 2 3 4 5 6 7
m1 = c^dpmodp
m2 = c^dqmodq
m = (((m1-m2)*I)%p)*q+m2
其中I为对pq求逆元
例题:BUUCTF RSA1
题目给出p,q,dp,dq,c没有e。
此时可以用上述公式求解,python脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12
import gmpy2 from Crypto.Util.number import long_to_bytes p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229 q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469 dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929 dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041 c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852 I = gmpy2.invert(q,p) m1 = pow(c,dp,p) m2 = pow(c,dq,q) m = (((m1-m2)*I)%p)*q+m2 print(long_to_bytes(m))