crypto-whatkey(2025YC行业赛)
题目给出一段加密程序:
from Crypto.Util.number import *
flag=b'flag{xxxxxxxxxxxx}'
m=bytes_to_long(flag)
p=getPrime(512)
q=getPrime(512)
n=p*q
d=getPrime(400)
phi=(p**3-1)*(q**3-1)
e=inverse(d,phi)
c=pow(m,e,n)
print(f'c=',c)
print(f'e=',e)
print(f'n=',n)
"""
c= 2003754706627487903851110616714304607189222178522389614780432514825573721438059633660697234750627981573886822017076810814538708354622058412946102754725288456603702128837517807891397774508307513050580105990618677049317133939305814694305278366577102584073129017412678522813682445801597908851296554932558669187
e= 919572382104578563852783535729668911795747292287824699748875787637132448617382830015807149791157476505111724164821800673674247548688068735634545433282365859265500801845407513575815722975624362309098629416368411642395098232251347235252285866711374932311058250940218140995891014054244315758844090650512583331163310780416670979259338009954277735170883115628072873670701645983940265444621569248489437615911135417054078642014957386887214400290541948239025348205900253189121094875716127730659125618727913604616492801132350421655995585775560874738471846791788049101552513726247367488945877250363652342477477379637540149275517826423349999124186630722415340888973638438207440091587197846199458869234025097517986953459695526825628918330778934148737115172589247148279283840510474329012339110291796227660004523993979762749015165634517124183625917926272544333044151354235866924430814366354881788831402961852599463936863202645755429190763
n= 131979662480380509369759579198983139290826765742675796288688133006553860359632346288809121984338652924319894805718486682190635020551003050891063247678206102622851484614406595912263202749897681245118168063240477660196297346135800054883127599820893151422473800035291575068378242690712493360122881743820716485153
"""
可以看出这段rsa加密有两个特点,第一是e值很大,远大于n。第二就是phi的计算方法比较特殊,无法用普通的rsa求解方法。
但通过仔细观察发现令p’=p**3,q’=q**3,则n’=n**3=p’q’,就可以套用普通的rsa求解方法了。
接下来针对e很大的情况,用rsa-wiener-attack方法进行攻击:
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGeneratordef hack_RSA(e,n):'''Finds d knowing (e,n)applying the Wiener continued fraction attack'''frac = ContinuedFractions.rational_to_contfrac(e, n)convergents = ContinuedFractions.convergents_from_contfrac(frac)for (k,d) in convergents:#check if d is actually the keyif k!=0 and (e*d-1)%k == 0:phi = (e*d-1)//ks = n - phi + 1# check if the equation x^2 - s*x + n = 0# has integer rootsdiscr = s*s - 4*nif(discr>=0):t = Arithmetic.is_perfect_square(discr)if t!=-1 and (s+t)%2==0:print("Hacked!")return ddef RSA():e = 919572382104578563852783535729668911795747292287824699748875787637132448617382830015807149791157476505111724164821800673674247548688068735634545433282365859265500801845407513575815722975624362309098629416368411642395098232251347235252285866711374932311058250940218140995891014054244315758844090650512583331163310780416670979259338009954277735170883115628072873670701645983940265444621569248489437615911135417054078642014957386887214400290541948239025348205900253189121094875716127730659125618727913604616492801132350421655995585775560874738471846791788049101552513726247367488945877250363652342477477379637540149275517826423349999124186630722415340888973638438207440091587197846199458869234025097517986953459695526825628918330778934148737115172589247148279283840510474329012339110291796227660004523993979762749015165634517124183625917926272544333044151354235866924430814366354881788831402961852599463936863202645755429190763n1 = 131979662480380509369759579198983139290826765742675796288688133006553860359632346288809121984338652924319894805718486682190635020551003050891063247678206102622851484614406595912263202749897681245118168063240477660196297346135800054883127599820893151422473800035291575068378242690712493360122881743820716485153n = n1 ** 3d = hack_RSA(e,n)print("d = ",d)if __name__ == "__main__":RSA()
算出d值以后就是简单的rsa解密了:
import gmpy2
from Crypto.Util.number import long_to_bytesn = 131979662480380509369759579198983139290826765742675796288688133006553860359632346288809121984338652924319894805718486682190635020551003050891063247678206102622851484614406595912263202749897681245118168063240477660196297346135800054883127599820893151422473800035291575068378242690712493360122881743820716485153
e = 919572382104578563852783535729668911795747292287824699748875787637132448617382830015807149791157476505111724164821800673674247548688068735634545433282365859265500801845407513575815722975624362309098629416368411642395098232251347235252285866711374932311058250940218140995891014054244315758844090650512583331163310780416670979259338009954277735170883115628072873670701645983940265444621569248489437615911135417054078642014957386887214400290541948239025348205900253189121094875716127730659125618727913604616492801132350421655995585775560874738471846791788049101552513726247367488945877250363652342477477379637540149275517826423349999124186630722415340888973638438207440091587197846199458869234025097517986953459695526825628918330778934148737115172589247148279283840510474329012339110291796227660004523993979762749015165634517124183625917926272544333044151354235866924430814366354881788831402961852599463936863202645755429190763
c = 2003754706627487903851110616714304607189222178522389614780432514825573721438059633660697234750627981573886822017076810814538708354622058412946102754725288456603702128837517807891397774508307513050580105990618677049317133939305814694305278366577102584073129017412678522813682445801597908851296554932558669187
# e很大,用rsa-wiener-attack-master里的脚本RSAwienerHacker.py得到d值
d = 2428133457992417057755374910442364655424627856010332229047718186512447631420713274083342651422856023482855592467077079459
m = pow(c,d,n)
print(long_to_bytes(m))