本文为人工撰写,仅使用生成式AI校对。
题目附件baby_next.py:
from Crypto.Util.number import *
from gmpy2 import next_prime
from functools import reduce
from secret import flag
assert len(flag) == 38
assert flag[:7] == b'moectf{'
assert flag[-1:] == b'}'
def main():
p = getPrime(512)
q = int(reduce(lambda res, _: next_prime(res), range(114514), p))
n = p * q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f'{n = }')
print(f'{c = }')
if __name__ == '__main__':
main()
"""
n = 96742777571959902478849172116992100058097986518388851527052638944778038830381328778848540098201307724752598903628039482354215330671373992156290837979842156381411957754907190292238010742130674404082688791216045656050228686469536688900043735264177699512562466087275808541376525564145453954694429605944189276397
c = 17445962474813629559693587749061112782648120738023354591681532173123918523200368390246892643206880043853188835375836941118739796280111891950421612990713883817902247767311707918305107969264361136058458670735307702064189010952773013588328843994478490621886896074511809007736368751211179727573924125553940385967
"""
注意到这是RSA加密,并且公钥(n, e)已给出,私钥缺少d。
所以我们需要和。
注意到:
令 ,
有 ,
所以有 ,
所以。
所以我们可以从开始寻找,只需要检验是否为完全平方数即可。
爆破脚本如下:
import math
from Crypto.Util.number import long_to_bytes
n = 96742777571959902478849172116992100058097986518388851527052638944778038830381328778848540098201307724752598903628039482354215330671373992156290837979842156381411957754907190292238010742130674404082688791216045656050228686469536688900043735264177699512562466087275808541376525564145453954694429605944189276397
c = 17445962474813629559693587749061112782648120738023354591681532173123918523200368390246892643206880043853188835375836941118739796280111891950421612990713883817902247767311707918305107969264361136058458670735307702064189010952773013588328843994478490621886896074511809007736368751211179727573924125553940385967
e = 65537
sn = math.isqrt(n)
print(sn)
a = sn
while(True):
b2 = a * a - n
if(b2 <= 0):
a += 1
continue
b = math.isqrt(b2)
if(b * b == b2):
print(f"a:{a}")
print(f"b:{b}")
print(f"p = a - b:{a - b}")
print(f"q = a + b:{a + b}")
lambdaN = math.lcm(a - b - 1, a + b - 1)
d = pow(e, -1, lambdaN)
m = pow(c, d, n)
print(f"m:{m}")
print(f"flag:{long_to_bytes(m)}")
break;
a += 1
输出:
9835790642950870702456388102541833011851580184211232019829465812360043670916676289614924432072209183922656300400121695605187082642402117584019839317552728
a:9835790642950870702456388102541833011851580184211232019829465812360043670916676289614924432072209183922656300400121695605187082642402117584019839317552729
b:20372862
p = a - b:9835790642950870702456388102541833011851580184211232019829465812360043670916676289614924432072209183922656300400121695605187082642402117584019839297179867
q = a + b:9835790642950870702456388102541833011851580184211232019829465812360043670916676289614924432072209183922656300400121695605187082642402117584019839337925591
m:13932707432295201762915447416760117532731261009261834621470110290846674770286488746417998205
flag:b'moectf{THIS_IS_FLAG}'