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

相关推荐
黄忠14 分钟前
大模型之LangGraph技术体系
python·llm
hboot13 小时前
AI工程师第二课 - 数据处理
人工智能·python·数据分析
用户83562907805118 小时前
使用 Python 自动化 PowerPoint 形状布局与格式设置
后端·python
用户83562907805119 小时前
用 Python 自动化 PowerPoint 演讲者备注添加
后端·python
黄忠1 天前
01-系统架构设计-LangGraph状态机与多源异构RAG
python
zzzzzz3101 天前
假如我是掘金管理员,我先给评论区装个'代码审查'系统
python·程序员·机器人
砍材农夫1 天前
python环境|conda安装和使用(2)
后端·python
程序员龙叔2 天前
编写高质量 Skill 系列 -- 如何设计需求分析与用例生成的 SKILL
自动化测试·软件测试·python·软件测试工程师·接口测试·性能测试·skill·ai测试
用户8356290780512 天前
使用 Python 操作 Word 内容控件
后端·python
LDR0062 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言