[NPUCTF2020]EzRSA

#attachment.py
from gmpy2 import lcm , powmod , invert , gcd , mpz
from Crypto.Util.number import getPrime
from sympy import nextprime
from random import randint
p = getPrime(1024)
q = getPrime(1024)
n = p * q
gift = lcm(p - 1 , q - 1)
e = 54722
flag = b'NPUCTF{******************}'
m = int.from_bytes(flag , 'big')
c = powmod(m , e , n)
print('n: ' , n)
print('gift: ' , gift)
print('c: ' , c)

#n:  17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121
#gift:  2135492653776686212553329560560967285303308936825887355911916917454772197960682240149821138177216833586509090969892419775958406087994054585022894165950768427741545736247918410255804894522085720642952579638418483800243368312702566458196708508543635051350999572787188236243275631609875253617015664414032058822919469443284453403064076232765024248435543326597418851751586308514540124571309152787559712950209357825576896132278045112177910266019741013995106579484868768251084453338417115483515132869594712162052362083414163954681306259137057581036657441897428432575924018950961141822554251369262248368899977337886190114104
#c:  3738960639194737957667684143565005503596276451617922474669745529299929395507971435311181578387223323429323286927370576955078618335757508161263585164126047545413028829873269342924092339298957635079736446851837414357757312525158356579607212496060244403765822636515347192211817658170822313646743520831977673861869637519843133863288550058359429455052676323196728280408508614527953057214779165450356577820378810467527006377296194102671360302059901897977339728292345132827184227155061326328585640019916328847372295754472832318258636054663091475801235050657401857262960415898483713074139212596685365780269667500271108538319

  

可以看到给了 n,p-1和q-1的最最小公倍数gift,密文c

用factordb分解一下试试

发现n果然无法分解,但是p-1和q-1的最最小公倍数gift可以分解

 

 

 

我们可以看到n的长度为2048

 

 

 gift的长度为2045

 

 

因为    gift*gcd((p-1),(q-1))==(p-1)*(q-1)
且     gift%gcd((p-1),(q-1))==0

 在因数中长度为3位左右的就是 2**3,测试一下

假设phi=gift*2**3

import sympy
import gmpy2
n =  17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121
gift = 2135492653776686212553329560560967285303308936825887355911916917454772197960682240149821138177216833586509090969892419775958406087994054585022894165950768427741545736247918410255804894522085720642952579638418483800243368312702566458196708508543635051350999572787188236243275631609875253617015664414032058822919469443284453403064076232765024248435543326597418851751586308514540124571309152787559712950209357825576896132278045112177910266019741013995106579484868768251084453338417115483515132869594712162052362083414163954681306259137057581036657441897428432575924018950961141822554251369262248368899977337886190114104
x = sympy.Symbol('x')
y = sympy.Symbol('y')
print sympy.solve([x*y-n,(x-1)*(y-1)-gift*8],[x,y])
p,q = sympy.solve([x*y-n,(x-1)*(y-1)-gift*8],[x,y])[0]
p,q = int(p),int(q)
assert p*q==n
assert gift == gmpy2.lcm(p - 1 , q - 1)

 

 

 

 

 

可以看到p和q是正确的。

接下来就是正常的解RSA

但是发现一个问题,gcd(e,phi)==2

d = gmpy2.invert(e/2,(p - 1)*(q - 1))
m_mid = pow(c,d,n)

 然后对m_mid进行开方,发现爆破不出来,应该是flag太长了。

只能用rabin了

import sympy
import gmpy2
n =  17083941230213489700426636484487738282426471494607098847295335339638177583685457921198569105417734668692072727759139358207667248703952436680183153327606147421932365889983347282046439156176685765143620637107347870401946946501620531665573668068349080410807996582297505889946205052879002028936125315312256470583622913646319779125559691270916064588684997382451412747432722966919513413709987353038375477178385125453567111965259721484997156799355617642131569095810304077131053588483057244340742751804935494087687363416921314041547093118565767609667033859583125275322077617576783247853718516166743858265291135353895239981121
gift = 2135492653776686212553329560560967285303308936825887355911916917454772197960682240149821138177216833586509090969892419775958406087994054585022894165950768427741545736247918410255804894522085720642952579638418483800243368312702566458196708508543635051350999572787188236243275631609875253617015664414032058822919469443284453403064076232765024248435543326597418851751586308514540124571309152787559712950209357825576896132278045112177910266019741013995106579484868768251084453338417115483515132869594712162052362083414163954681306259137057581036657441897428432575924018950961141822554251369262248368899977337886190114104
x = sympy.Symbol('x')
y = sympy.Symbol('y')
print sympy.solve([x*y-n,(x-1)*(y-1)-gift*8],[x,y])
p,q = sympy.solve([x*y-n,(x-1)*(y-1)-gift*8],[x,y])[0]
p,q = int(p),int(q)
assert p*q==n
assert gift == gmpy2.lcm(p - 1 , q - 1)
c = 3738960639194737957667684143565005503596276451617922474669745529299929395507971435311181578387223323429323286927370576955078618335757508161263585164126047545413028829873269342924092339298957635079736446851837414357757312525158356579607212496060244403765822636515347192211817658170822313646743520831977673861869637519843133863288550058359429455052676323196728280408508614527953057214779165450356577820378810467527006377296194102671360302059901897977339728292345132827184227155061326328585640019916328847372295754472832318258636054663091475801235050657401857262960415898483713074139212596685365780269667500271108538319
e = 54722
d = gmpy2.invert(e/2,(p - 1)*(q - 1))
m_mid = pow(c,d,n)
print m_mid

# Euler's criterion
def legendre_symbol(a, p):
    symbol = pow(a, (p - 1) // 2, p)
    if symbol == p - 1:
        return -1
    return symbol

def sqrt_mod(a, p):
    if a == 0 or legendre_symbol(a, p) != 1:
        return 0
    if p % 4 == 3:
        return pow(a, (p + 1) // 4, p)
    if p % 8 == 5:
        if pow(a, (p - 1) // 4, p) == 1:
            return pow(a, (p + 3) // 8, p)
        else:
            return (pow(2, (p - 1) // 4, p) * pow(a, (p + 3) // 8, p)) % p

    q = p - 1
    s = 0
    while q & 1 == 0:
        q >>= 1
        s += 1

    z = 2
    while legendre_symbol(z, p) != -1:
        z += 1

    m = s
    c = pow(z, q, p)
    t = pow(a, q, p)
    r = pow(a, (q + 1) // 2, p)

    while t != 1:
        t2 = t
        i = 0
        while t2 != 1 and i < m:
            t2 = pow(t2, 2, p)
            i += 1

        b = pow(c, 2 ** (m - i - 1), p)
        m = i
        c = (b * b) % p
        t = (t * c) % p
        r = (r * b) % p

    return r


r = sqrt_mod(m_mid, p)
s = sqrt_mod(m_mid, q)
a = gmpy2.invert(p, q)
b = gmpy2.invert(q, p)
x = (a*p*s+b*q*r) % n
y = (a*p*s-b*q*r) % n
from Crypto.Util.number import *
print repr(long_to_bytes(x % n))
print repr(long_to_bytes((-x) % n))
print repr(long_to_bytes(y % n))
print repr(long_to_bytes((-y) % n))

 得到flag

 

 

 

posted @ 2020-04-30 18:02  S4tan  阅读(1755)  评论(0编辑  收藏  举报