Buuctf 新生赛 easy_Rsa题解
本题目的是使新生对rsa更加熟悉,一个题目内含五个小问。
🏎️ 题干
assert len(flag) % 5 == 0 cnt = len(flag) // 5 flags = [flag[cnt*i:cnt*(i+1)] for i in range(5)]
我们根据题干不难发现,这一题的flag是由五个小问输出拼接在一起的.
1.已知p q e c 求m
m = bytes_to_long(message) c = 22160015525054597533062795679117215923801827397299805735087138192137742945881204146337349060934854888054628153923021387981306839951210090523829296521835965212118849043671673133979884712755090374758002677916820953359774554825569218497687506468472278309097929775388010403607769802840990547048001743970754496905 p = 6962443023774446497102092246794613339314677593117417573764609329949026862782472380488956732038459060928443992561763464365758383525259954798321350043810351 q = 9631855759661411029901156175243744760977799976661519182223576693685069000499866459636568713055906075171480855575061732016121299027658733834671035383233163 e = 0x10001
下面给出解题脚本:
import gmpy2 import Crypto.Util.number c = p = q = n = p*q e = phi = (p-1)*(q-1) d = gmpy2.invert(e,phi) m =pow(c,d,n) m=Crypto.Util.number.long_to_bytes(m) print(m)
2.已知c,n,e求m
c = 17250922799297131008803303235771955129 n = 134097988095851988085603926250918812377 e = 0x10001 m = bytes_to_long(message)
首先分析题目,我们的目标是分解因数得到p,q,由于n比较小,我们可以在网站上分解因数。
下面给出网站:分解质因数工具 - 整数分解最多为70位
分解完以后,便是第一题的类型。
3.已知c,n,e,求m
c = 2776571135646565181849912433877522437622755332262910824866791711 n = 85793694792655420934945863688968944466300304898903354212780512650924132933351787673979641944071634528676901506049360194331553838080226562532784448832916022442020751986591703547743056267118831445759258041047213294368605599719242059474324548598203039032847591828382166845797857139844445858881218318006747115157 e = 3
分析本题可以发现e远小于n,在求d时则会出现问题,而且n偏大,质数因式分解也困难。
题中e=3相对于n,c来说极小,故可知是低加密指数攻击。
①当 m ^3 < n 时 , c = m ^3 , 直 接 将 c 开 三 次 方 即 可 得 到 m
②当 m^ 3 > n 时 , c = m^ 3 - i ∗ n , 只 要 找 到 i , 使 得 c + i n 能 够 开 三 次 方 即 可 得 到m
下面给出脚本:
import gmpy2 import binascii e = n = c = 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:]))
4.已知c,e,n,求m
c = 68588738085497640698861260094482876262596289469248772328560280530093163764972313090939471997156632421517452790632223565521726590730640805290182026911025142051864898712501214753986865172996090706657535814234291235489829621372021092488300236623525366939477695283380634188510950335639019458758643273802572617191 e = 51999725233581619348238930320668315462087635295211755849675812266270026439521805156908952855288255992098479180003264827305694330542325533165867427898010879823017054891520626992724274019277478717788189662456052796449734904215067032681345261878977193341769514961038309763898052908572726913209883965288047452751 n = 68816697240190744603903822351423855593899797203703723038363240057913366227564780805815565183450516726498872118491739132110437976570592602837245705802946829337567674506561850972973663435358068441037127926802688722648016352967768929007662772115485020718202683004813042834036078650571763978066558718285783045969
分析题目,题中e很大,故可知是低解密指数攻击。
可以使用破解脚本:求出d的值,文件下载地址GitHub - pablocelayes/rsa-wiener-attack: A Python implementation of the Wiener attack on RSA public-key encryption scheme.
(注意,这里要将破解脚本和rsa-wiener-attack的py文件放在同一个目录下)
脚本如下:
import binascii import RSAwienerHacker e = n = c = d = RSAwienerHacker.hack_RSA(e,n) m = gmpy2.powmod(c,d,n) print(binascii.unhexlify(hex(m)[2:]))
5.已知c,hint,n,e求m
c = 1135954814335407362237156338232840769700916726653557860319741136149066730262056907097728029957898420630256832277578506404721904131425822963948589774909272408535427656986176833063600681390871582834223748797942203560505159946141171210061405977060061656807175913366911284450695116982731157917343650021723054666494528470413522258995220648163505549701953152705111304471498547618002847587649651689203632845303117282630095814054989963116013144483037051076441508388998829 hint = 611144874477135520868450203622074557606421849009025270666985817360484127602945558050689975570970227439583312738313767886380304814871432558985582586031211416586296452510050692235459883608453661597776103386009579351911278185434163016083552988251266501525188362673472772346212970459561496301631587043106524741903627979311997541301471894670374945556313285203740782346029579923650160327646876967315182335114575921178144825057359851607166387868294019144940296084605930 n = 1232865496850144050320992645475166723525103370117149219196294373695624167653495180701004894188767069545579706264513808335877905149818445940067870026924895990672091745229251935876434509430457142930654307044403355838663341948471348893414890261787326255632362887647279204029327042915224570484394917295606592360109952538313570951448278525753313335289675455996833500751672463525151201002407861423542656805624090223118747404488579783372944593022796321473618301206064979 n = p * p * q e = 0x10001 d = inverse(e, p * (p-1) * (q-1)) assert m < n c = pow(m, e, n) hint = pow(d, e, n)
这一道题目需要进行模运算。p q无法啊直接通过n分解出来,但仔细分析n和phi(n)我们可以发现公约数是p,那么我们的突破点就在这。
通过题目可以发现直接求出phi(n)是不切实际的,那我们只需要让phi存在于某一个式子即可。
下面给出脚本:
from Crypto.Util.number import * import math import gmpy2 import Crypto.Util.number n=1232865496850144050320992645475166723525103370117149219196294373695624167653495180701004894188767069545579706264513808335877905149818445940067870026924895990672091745229251935876434509430457142930654307044403355838663341948471348893414890261787326255632362887647279204029327042915224570484394917295606592360109952538313570951448278525753313335289675455996833500751672463525151201002407861423542656805624090223118747404488579783372944593022796321473618301206064979 hint=611144874477135520868450203622074557606421849009025270666985817360484127602945558050689975570970227439583312738313767886380304814871432558985582586031211416586296452510050692235459883608453661597776103386009579351911278185434163016083552988251266501525188362673472772346212970459561496301631587043106524741903627979311997541301471894670374945556313285203740782346029579923650160327646876967315182335114575921178144825057359851607166387868294019144940296084605930 c =1135954814335407362237156338232840769700916726653557860319741136149066730262056907097728029957898420630256832277578506404721904131425822963948589774909272408535427656986176833063600681390871582834223748797942203560505159946141171210061405977060061656807175913366911284450695116982731157917343650021723054666494528470413522258995220648163505549701953152705111304471498547618002847587649651689203632845303117282630095814054989963116013144483037051076441508388998829 e =0x10001 x=pow(e,e,n) #求出e**e模n y = gmpy2.invert(x, n) #求出1/(e*e)模n a = (hint-y)%n p=math.gcd(a,n) q=n//p**2 phi = (p - 1) * (q - 1)*p d = gmpy2.invert(e, phi) m=pow(c,d,n) m=Crypto.Util.number.long_to_bytes(m) print(m)
将以上m拼在一起便是flag。
---在此感谢猫神的帮忙