[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 参数构造失误 + 小指数攻击

相关推荐
用户83562907805113 分钟前
如何使用 Python 将 PowerPoint 转换为 PDF 文档
后端·python
菜冻鱼13 分钟前
Python-pytorch-高级技巧
开发语言·人工智能·pytorch·python·深度学习·神经网络·聚类
lpfasd12315 分钟前
python webview打包版卡死、开发版正常
开发语言·python
用户83562907805124 分钟前
如何使用 Python 为 PowerPoint 幻灯片添加切换效果
后端·python
weixin_4614085827 分钟前
npm npx yarn
开发语言·前端·javascript
菜冻鱼32 分钟前
Python-pytorch-模型保存与加载
开发语言·人工智能·pytorch·python·深度学习·机器学习
骇客野人35 分钟前
Java SSO 统一认证方案
java·开发语言
亿牛云爬虫专家1 小时前
爬虫调度系统设计:用 Celery 实现按媒体权重动态调整的抓取频率控制
爬虫·python·隧道代理·舆情采集·媒体权重·频率控制·ip自动轮换
Code额2 小时前
Python 连接 DeepSeek API,OpenAI
开发语言·python·ai·ai编程
-凌凌漆-2 小时前
【freertos】Task创建(v2)
java·开发语言·算法