[羊城杯 2023]Danger_RSA

题目:

from Crypto.Util.number import *

m = bytes_to_long(flag)

def get_key(a, nbit):
    assert a >= 2
    while True:
        X = getRandomInteger(nbit // a)
        s = getRandomRange(pow(2, a ** 2 - a + 4), pow(2, a ** 2 - a + 5))
        p = X ** a + s
        if isPrime(p):
            return (p, s)

p, s = get_key(a, 1024)
q, t = get_key(a, 1024)

N = p * q
e = s * t
c = pow(m, e, N)
print("N =", N)
print("e =", e)
print("c =", c)
# N = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
# e = 11079917583
# c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766

解题思路:

  • 这里p=X<sup>a</sup>+s,q=Y<sup>a</sup>+t

X,Y是一个随机的nbit/a位整数,s,t是一个随机的范围在[2<sup>a^2−a+4</sup>,2<sup>a^2−a+5</sup>)的整数

  • e=s*t,N=p*q
import math
number = 11079917583
bit_length = math.ceil(math.log2(number))
print(bit_length)
#34

既然s,t在基于a的小范围内随机,且知道ebit值34,那么猜测s,tbit值为都17

那么要使s的比特值为17,s必须满足:2<sup>16</sup>≤s<2<sup>17</sup>

因此,我们需要解方程:<font style="color:rgb(6, 6, 7);">a</font><sup><font style="color:rgb(6, 6, 7);">2</font></sup><font style="color:rgb(6, 6, 7);">−a+4=16</font>,最后解得正数<font style="color:rgb(6, 6, 7);">a</font><font style="color:rgb(6, 6, 7);">4</font>

  • 我们把e分解后得到e=3×7<sup>2</sup>×19×691×5741选出合适的乘积作为s,t
import itertools
from functools import reduce
from operator import mul
x = [3, 7, 7, 19, 691, 5741]
c = 1
num = set()
for j in range(1, 7):
    for i in itertools.product(x, repeat=j):
        p = c * reduce(mul, i)
        if p.bit_length() == 17:
            num.add(p)
print(num)
#{68229, 130599, 101577, 123823, 120561, 118161, 130321, 117649, 109079, 91903}
  • 这是st的所有可能性,然后再尝试选出合适的乘积作为s,t

因为p=X<sup>4</sup>+s,q=Y<sup>4</sup>+t,所以p≈X<sup>4</sup>,q≈Y<sup>4</sup>,则n≈(XY)<sup>4</sup>⟶XY=n<sup>1/4</sup>

得到XY之后,联立n=(X<sup>4</sup>+s)(Y<sup>4</sup>+t)

解出X,Y这里要注意的是s,t要选合适才有整数解

import gmpy2
import itertools
from sympy import symbols, solve

n = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
data = [68229, 130599, 101577, 123823, 120561, 118161, 130321, 117649, 109079, 91903]

XY = int(gmpy2.iroot(n, 4)[0])
print("XY:", XY)

date = [i for i in itertools.combinations(data, 2)]
X, Y = symbols('X Y')
for s, t in date:
    if s * t != e:
        continue
    f1 = X * Y - XY
    f2 = n - ((X**4 + s) * (Y**4 + t))
    tmp = solve((f1, f2), (X, Y))
    if tmp:
        print("解得 X, Y:", tmp)
        print("s, t:", s, t)

'''
XY: 2122361604964166393417939623970620172320518010305971917186304222196039261526022883781187162128451069598061455410691917162002974796704890013196188763171844
解得 X, Y: [(-44416071018427916652440592614276227563515579156219730344722242565477265479486*19**(3/4)*21**(1/4)/19, -47783641287938625512681830427927501009821495321018170621907812035456872958654*19**(1/4)*21**(3/4)/21), (44416071018427916652440592614276227563515579156219730344722242565477265479486*19**(3/4)*21**(1/4)/19, 47783641287938625512681830427927501009821495321018170621907812035456872958654*19**(1/4)*21**(3/4)/21), (-47783641287938625512681830427927501009821495321018170621907812035456872958654*4837**(1/4)*5741**(3/4)/5741, -44416071018427916652440592614276227563515579156219730344722242565477265479486*4837**(3/4)*5741**(1/4)/4837), (47783641287938625512681830427927501009821495321018170621907812035456872958654*4837**(1/4)*5741**(3/4)/5741, 44416071018427916652440592614276227563515579156219730344722242565477265479486*4837**(3/4)*5741**(1/4)/4837), (-44416071018427916652440592614276227563515579156219730344722242565477265479486*19**(3/4)*21**(1/4)*I/19, 47783641287938625512681830427927501009821495321018170621907812035456872958654*19**(1/4)*21**(3/4)*I/21), (44416071018427916652440592614276227563515579156219730344722242565477265479486*19**(3/4)*21**(1/4)*I/19, -47783641287938625512681830427927501009821495321018170621907812035456872958654*19**(1/4)*21**(3/4)*I/21), (-47783641287938625512681830427927501009821495321018170621907812035456872958654*4837**(1/4)*5741**(3/4)*I/5741, 44416071018427916652440592614276227563515579156219730344722242565477265479486*4837**(3/4)*5741**(1/4)*I/4837), (47783641287938625512681830427927501009821495321018170621907812035456872958654*4837**(1/4)*5741**(3/4)*I/5741, -44416071018427916652440592614276227563515579156219730344722242565477265479486*4837**(3/4)*5741**(1/4)*I/4837)]
s, t: 101577 109079
解得 X, Y: [(-47783641287938625512681830427927501009821495321018170621907812035456872958654, -44416071018427916652440592614276227563515579156219730344722242565477265479486), (47783641287938625512681830427927501009821495321018170621907812035456872958654, 44416071018427916652440592614276227563515579156219730344722242565477265479486), (-47783641287938625512681830427927501009821495321018170621907812035456872958654*I, 44416071018427916652440592614276227563515579156219730344722242565477265479486*I), (47783641287938625512681830427927501009821495321018170621907812035456872958654*I, -44416071018427916652440592614276227563515579156219730344722242565477265479486*I), (-44416071018427916652440592614276227563515579156219730344722242565477265479486*13129**(3/4)*17223**(1/4)/13129, -47783641287938625512681830427927501009821495321018170621907812035456872958654*13129**(1/4)*17223**(3/4)/17223), (44416071018427916652440592614276227563515579156219730344722242565477265479486*13129**(3/4)*17223**(1/4)/13129, 47783641287938625512681830427927501009821495321018170621907812035456872958654*13129**(1/4)*17223**(3/4)/17223), (-44416071018427916652440592614276227563515579156219730344722242565477265479486*13129**(3/4)*17223**(1/4)*I/13129, 47783641287938625512681830427927501009821495321018170621907812035456872958654*13129**(1/4)*17223**(3/4)*I/17223), (44416071018427916652440592614276227563515579156219730344722242565477265479486*13129**(3/4)*17223**(1/4)*I/13129, -47783641287938625512681830427927501009821495321018170621907812035456872958654*13129**(1/4)*17223**(3/4)*I/17223)]
s, t: 120561 91903
'''
  • 满足条件的整数结果为
X=47783641287938625512681830427927501009821495321018170621907812035456872958654
Y=44416071018427916652440592614276227563515579156219730344722242565477265479486
s=120561
t=91903
  • 然后还原p,q,发现ephip-1q-1均不互素(用e,phi不互素做没逆元)
from gmpy2 import *
X = 47783641287938625512681830427927501009821495321018170621907812035456872958654
Y = 44416071018427916652440592614276227563515579156219730344722242565477265479486
s = 120561
t = 91903
e = 11079917583
p = X**4 + s
q = Y**4 + t
phi = (p-1)*(q-1)
print(gcd(e,phi))
print(gcd(e,p-1))
print(gcd(e,q-1))
#21
#3
#7
  • 用有限域的开方加CRT求解
e = 11079917583
p = 5213351003420231819415242686664610206224730148063270274863722096379841592931572096469136339538500817713355302889731144789372844731378975059329731297860686270736540109105854515590165681366189003405833252270606896051264517339339578167231093908235856718285980689179840159807651185918046198419707669304960745217
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766
R = Zmod(p)['x']; (x,) = R._first_ngens(1) #模p的意义下定义了一个多项式环R
f = x ** e - c
f = f.monic()
res1 = f.roots()
print(res1)
e = 11079917583
q = 3891889986375336330559716098591764128742918441309724777337583126578227827768865619689858547513951476952436981068109005313431255086775128227872912287517417948310766208005723508039484956447166240210962374423348694952997002274647622939970550008327647559433222317977926773242269276334110863262269534189811138319
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766
R = Zmod(q)['x']; (x,) = R._first_ngens(1) #模q的意义下定义了一个多项式环R
f = x ** e - c
f = f.monic()
res2 = f.roots()
print(res2)
  • MemoryError:…………e太大了,溢出了
  • 不过一般flag没有填充的情况下会小于p,所以用p,q单独作公钥求解

d = gmpy2.invert(e // 21,p - 1)

  • 在模p下求解出m<sup>21 </sup>≡ c<sup>d </sup>mod p,再用多项式环求根

解答:

e = 11079917583
p = 5213351003420231819415242686664610206224730148063270274863722096379841592931572096469136339538500817713355302889731144789372844731378975059329731297860686270736540109105854515590165681366189003405833252270606896051264517339339578167231093908235856718285980689179840159807651185918046198419707669304960745217
q = 3891889986375336330559716098591764128742918441309724777337583126578227827768865619689858547513951476952436981068109005313431255086775128227872912287517417948310766208005723508039484956447166240210962374423348694952997002274647622939970550008327647559433222317977926773242269276334110863262269534189811138319
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766

d = inverse_mod(e // 21, p - 1)
m_21 = pow(c, d, p)
# 求出 m 的 21 次方根
e = 21
R = PolynomialRing(Zmod(p), 'x')
f = R.gen()**e - m_21
f = f.monic()
mps = f.roots()
for i in mps:
    root_value = int(i[0])
    flag = root_value.to_bytes((root_value.bit_length() + 7) // 8, 'big')
    if b'DASCTF' in flag:
        print(flag)
#DASCTF{C0nsTruct!n9_Techn1qUe2_f0r_RSA_Pr1me_EnC2ypt10N}
posted @ 2025-03-12 00:02  sevensnight  阅读(49)  评论(0)    收藏  举报