import gmpy2 from Crypto.Util.number import long_to_bytes
q = 189239861511125143212536989589123569301 p = 386123125371923651191219869811293586459
e = 65537 c = 28767758880940662779934612526152562406674613203406706867456395986985664083182 # n = 73069886771625642807435783661014062604264768481735145873508846925735521695159 n = q*p # print(n) d = gmpy2.invert(e, (p - 1) * (q - 1)) print("d=",d) m = pow(c, d, n) print(m) print(long_to_bytes(m))
运行即可得到flag,这也是最常规的解密RSA的脚本结构。
这里python脚本需要一个gmpy2模块,这是密码学中非常重要的一个模块,pip安装就行了。
思路二、低加密指数攻击(e很小)
适用情况:n很大但是e很小,一般e=3
n很大时我们就不能因式分解了,当然还有其他思路,
例如当e很小时,比如e=3,有,我们可以对k进行爆破,直到可以开根,借此得到m。
例题:BUUCTF DangrousRSA
题目的n很大,但e仅仅是3,此时我们就可以进行低加密指数攻击,python脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
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
e = 65537 n=[] c=[] p=[] for i inrange(1,20): n.append(eval('n'+str(i))) c.append(eval('c'+str(i))) data=list(zip(n,c)) for i inrange(len(n)): for j inrange(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))
#低解密指数攻击,使用 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 inrange(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)