[NewStarCTF 2023 公开赛道]eazy_crt

MagicianV RSA 题解(WP)

题目源码:

复制代码
from Crypto.Util.number import *
from secret import flag, p, q
from hashlib import *
import random

assert 'flag{' + md5(str(p).encode()).hexdigest() + '}' == flag
assert isPrime(p), isPrime(q)
assert p.bit_length() == 1024, q.bit_length() == 1024

m = random.getrandbits(400)
e = 65537
d = inverse(e, (p - 1) * (q - 1))
r1, r2, r3 = getPrime(20), getPrime(20), getPrime(10)

dp, dq = d % (p - 1), d % (q - 1)
Sp, Sq = pow(m + getPrime(10), dp, r1 * p), pow(m, dq, r2 * q)
s1, s2 = pow(m, dp % (r1 - 1), r1), pow(m, dq % (r2 - 1), r2)

S_ = Sq + (q * r2) * (int(inverse(q * r2, p * r1)) * (Sp - Sq) % (p * r1))

c1, c2 = (S_ - s1 + 1) % r1, (S_ - s2 + 1) % r2

gamma = (r3 * c1 + (2 ** 10 - r3) * c2) // (2 ** 10)

S = pow(S_, gamma, p * q)

给出了:

  • m

  • n = p*q

  • S_

  • S

目标:

复制代码
flag = flag{md5(str(p))}

所以核心是:

分解 n


一、观察关键点

最关键的一句:

复制代码
S = pow(S_, gamma, n)

即:

复制代码
S ≡ S_^gamma mod n

这里:

复制代码
gamma = (r3 * c1 + (2 ** 10 - r3) * c2) // (2 ** 10)

其中:

  • r3 是 10 bit 素数

  • c1 < r1

  • c2 < r2

  • r1,r2 是 20 bit 素数

因此:

gamma 很小

数量级:

复制代码
gamma < 2^20

二、爆破 gamma

因为:

复制代码
S = S_^gamma mod n

而:

复制代码
gamma < 2^20

所以直接暴力:

复制代码
for g in range(2**20):
    if pow(S_, g, n) == S:
        print(g)

得到:

复制代码
gamma = 337756

三、利用 gamma 分解 n

由于:

复制代码
S ≡ S_^gamma mod n

则:

复制代码
S_^gamma - S ≡ 0 mod n

即:

复制代码
n | (S_^gamma - S)

这意味着:

复制代码
pow(S_, gamma, n) - S

n 存在巨大关系。

进一步考虑:

RSA 中常用:

复制代码
gcd(a^k - b, n)

去提取因子。

于是尝试:

复制代码
g = gcd(pow(S_, gamma) - S, n)

即可得到:

复制代码
p

随后:

复制代码
q = n // p

完成分解。


四、计算 flag

题目:

复制代码
flag = flag{md5(str(p))}

因此:

复制代码
from hashlib import md5

flag = "flag{" + md5(str(p).encode()).hexdigest() + "}"

得到:

复制代码
flag{b40ea076da8c73572ae5d067aa0fc22e}

五、完整 EXP

复制代码
from Crypto.Util.number import *
from hashlib import md5
from math import gcd

m = ...
n = ...
S_ = ...
S = ...

for gamma in range(1 << 20):
    if pow(S_, gamma, n) == S:
        print("[+] gamma =", gamma)
        break

x = pow(S_, gamma) - S
p = gcd(x, n)
q = n // p

print("[+] p =", p)
print("[+] q =", q)

flag = "flag{" + md5(str(p).encode()).hexdigest() + "}"
print(flag)

六、题目考点

这题核心是:

小指数泄露

由于:

复制代码
gamma < 2^20

导致:

复制代码
S = S_^gamma mod n

可以直接离散爆破。

随后通过:

复制代码
gcd(pow(S_, gamma) - S, n)

恢复 RSA 因子。

本质属于:

RSA 参数构造失误 + 小指数攻击

相关推荐
Csvn6 分钟前
Python 开发技巧 · 生成器(Generator)进阶 —— 从 yield 到 yield from,写出省内存的生产者-消费者模式
后端·python
geovindu8 分钟前
CSharp: Dijkstra Algorithms
开发语言·后端·算法·c#
XR12345678814 分钟前
食品饮料与制药行业GMP合规网络建设:无尘车间的网络不能成为污染源
开发语言·网络·php
GEO_ai_zhijian21 分钟前
口碑好的工业GEO优秀企业
python·搜索引擎
mikejahn22 分钟前
解析ISO网站单个标准的静态网址
python
学逆向的33 分钟前
汇编——位运算
开发语言·汇编·算法·网络安全
zhangjw3440 分钟前
第29篇:Java伪共享与对象分配:并发性能优化的关键
java·开发语言·性能优化
Java面试题总结1 小时前
Python 开发技巧 · 高级装饰器 —— 从基础到工业级实战
开发语言·python
纸小铭2 小时前
[MAF预定义ChatClient中间件-01]LoggingChatClient——在调用LLM前后输出日志
python·中间件·flask
aiqianji2 小时前
有哪些支持长文的AI生成短篇小说软件?
人工智能·python