news 2026/7/9 1:05:19

Bugku CTF Crypto - MaybeEasyRSA 题解(欧拉定理的应用)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Bugku CTF Crypto - MaybeEasyRSA 题解(欧拉定理的应用)

前言

Bugku CTF 是国内知名的网络安全竞赛训练平台,涵盖了 Web、Crypto、Misc、Reverse、Pwn 等多个方向的题目。“MaybeEasyRSA” 是一道 Crypto 类的题目,分值 15 分,从题目名就能猜到和 RSA 加密有关——但加了个 “Maybe”,似乎在暗示它并不是那么 “Easy”。

RSA 是现代密码学的基石之一,其安全性建立在大整数分解的困难性之上。而 RSA 加解密的核心数学工具正是欧拉定理:若 p 和 q 是两个大素数,则欧拉函数 φ(n) = (p-1)(q-1),私钥 d 满足 ed ≡ 1 (mod φ(n))。本题正是围绕欧拉定理展开,但由于 p 和 q 并非随机素数,而是由一个共同的 r 衍生而来,使得直接分解 n 成为可能。

题目描述

题目给出了三个关键数值:模数 n、公钥指数 e 和密文 c。在本题中,p 和 q 的生成方式并非标准的随机大素数,而是由一个共同的整数 r 通过多项式构造,再取 nextprime 得到:

p1=r**5+r**4-r**3+r**2-r+2024
p=nextprime(p1)

q1=r**5-r**4+r**3-r**2+r+2024
q=nextprime(q1)

n=p*q

本题示例数据如下:

  • n= 8831809262643652126805179955933995088022863336420177785582181882096928010834594263850405726350879463
  • e= 65537
  • c= 4187685979531305196335859680920102897998391621267133257213664500289506210489114078388515813179920201

n 的量级约为 333 bit,属于可分解范围。但真正的考点不在于直接分解 n,而在于发现 p 和 q 的结构规律。

解题思路

观察:pq由同一个r衍生

注意到 p1 和 q1 的表达式中,最高次项都是 r^5,而且 q1 的构造与 p1 高度对称(各项符号交替反转)。因为 p = nextprime(p1) ≈ p1、q = nextprime(q1) ≈ q1,所以:

n = p × q ≈ p1 × q1 ≈ r^5 × r^5 = r^10

这意味着,如果我们能求出 r,就能重建 p 和 q,进而利用欧拉定理完成解密。问题的本质从”分解 n”转化为”求 r”。

n10次方得到r近似值

既然 n ≈ r^10,我们对 n 开 10 次方就能得到 r 的近似值。使用 Python 的 gmpy2 库:

r_approx=int(gmpy2.iroot(n,10)[0])

由于 p 和 q 是 nextprime 的结果(比 p1 和 q1 略大),n 会略大于 r^10,所以开方得到的 r_approx 会非常接近真实的 r,通常偏差在个位数到几十之间。

在近似值附近搜索精确r

在 r_approx 的邻域内搜索。对每个候选 r_test,计算 p_test = nextprime(r_test^5 + r_test^4 - r_test^3 + r_test^2 - r_test + 2024),然后用 n % p_test == 0 验证:

foroffsetinrange(-2000,2001):
r_test=r_approx+offset
ifr_test<=0:
continue
p_test=get_p(r_test)
ifn%p_test==0:
found_r=r_test
break

一旦找到满足条件的 r,就说明 p 和 q 对应的原始 r 值被精确定位。

r重建pq

找到精确 r 后,重新计算 p 和 q:

p=get_p(found_r)
q=get_q(found_r)
assertp*q==n# 验证正确性

利用欧拉定理计算φ(n)和私钥d

欧拉定理指出:若 a 与 n 互素,则 a^φ(n) ≡ 1 (mod n)。在 RSA 中,由于 n = p × q(p、q 为素数),欧拉函数为:

φ(n) = (p-1)(q-1)

私钥 d 是 e 关于模 φ(n) 的乘法逆元:

ed ≡ 1 (mod φ(n))d = e^(-1) mod φ(n)

phi_n=(p-1)*(q-1)
d=int(gmpy2.invert(e, phi_n))

解密得到flag

用私钥 d 解密密文 c:

m = c^d mod n

再将大整数 m 转换为字节串:

m=pow(c, d, n)
flag=long_to_bytes(m)

解题代码

"""
Bugku CTF - MaybeEasyRSA 完整解题脚本
题目链接: https://ctf.bugku.com/challenges/detail/id/2413.html

核心思路:
1. p 和 q 由同一个 r 衍生: p1 = r^5+r^4-r^3+r^2-r+2024, p = nextprime(p1)
q 类似对称构造: q1 = r^5-r^4+r^3-r^2+r+2024, q = nextprime(q1)
2. n = p*q ≈ r^10, 对 n 开 10 次方得到 r 的近似值
3. 在近似值附近搜索精确的 r
4. 用 r 重建 p 和 q
5. 利用欧拉定理 φ(n) = (p-1)(q-1), 计算私钥 d
6. 解密得到 flag
"""

importgmpy2
fromCrypto.Util.numberimportlong_to_bytes

# ==================== 题目给定数据 ====================
n=8831809262643652126805179955933995088022863336420177785582181882096928010834594263850405726350879463
e=65537
c=4187685979531305196335859680920102897998391621267133257213664500289506210489114078388515813179920201

print("="*60)
print("Bugku CTF - MaybeEasyRSA 解题")
print("="*60)

# ==================== 步骤 1: 对 n 开 10 次方求 r 近似值 ====================
# n = p * q ≈ r^10(因为 p ≈ r^5, q ≈ r^5)
r_approx, exact=gmpy2.iroot(n,10)
r_approx=int(r_approx)
print(f"\n[步骤1] 对 n 开 10 次方, 得到 r 的近似值:")
print(f" r_approx ={r_approx}")
print(f" n 的位数:{n.bit_length()}bit")

# ==================== 步骤 2: 在近似值附近搜索精确的 r ====================
defget_p(r):
"""根据 r 计算 p = nextprime(r^5 + r^4 - r^3 + r^2 - r + 2024)"""
p1=r**5+r**4-r**3+r**2-r+2024
returnint(gmpy2.next_prime(p1))

defget_q(r):
"""根据 r 计算 q = nextprime(r^5 - r^4 + r^3 - r^2 + r + 2024)"""
q1=r**5-r**4+r**3-r**2+r+2024
returnint(gmpy2.next_prime(q1))

print(f"\n[步骤2] 在 r_approx 附近搜索精确的 r 值:")
found_r=None
search_range=2000
foroffsetinrange(-search_range, search_range+1):
r_test=r_approx+offset
ifr_test<=0:
continue
p_test=get_p(r_test)
ifn%p_test==0:
found_r=r_test
print(f" 搜索偏移量:{offset}")
print(f" 找到精确 r ={found_r}")
break

# ==================== 步骤 3: 用 r 重建 p 和 q ====================
print(f"\n[步骤3] 用 r ={found_r}重建 p 和 q:")
p=get_p(found_r)
q=get_q(found_r)
print(f" p1 = r^5 + r^4 - r^3 + r^2 - r + 2024")
print(f" p = nextprime(p1) ={p}")
print(f" q1 = r^5 - r^4 + r^3 - r^2 + r + 2024")
print(f" q = nextprime(q1) ={q}")
print(f" 验证: p * q == n ?{p*q==n}")

# ==================== 步骤 4: 欧拉定理计算私钥 ====================
# φ(n) = (p-1)(q-1)
# ed ≡ 1 (mod φ(n)) → d = e^{-1} mod φ(n)
print(f"\n[步骤4] 利用欧拉定理 φ(n) = (p-1)(q-1) 计算私钥 d:")
phi_n=(p-1)*(q-1)
d=int(gmpy2.invert(e, phi_n))
print(f" φ(n) = (p-1)*(q-1)")
print(f" φ(n) 长度:{phi_n.bit_length()}bit")
print(f" d = e^(-1) mod φ(n)")
print(f" d ={d}")

# ==================== 步骤 5: RSA 解密 ====================
print(f"\n[步骤5] RSA 解密: m = c^d mod n")
m=pow(c, d, n)
print(f" m ={m}")

# ==================== 步骤 6: 提取 flag ====================
print(f"\n[步骤6] 将明文 m 转为 bytes 得到 flag:")
flag=long_to_bytes(m)
print(f" flag ={flag}")

print("\n"+"="*60)
print(f"Flag:{flag.decode()}")
print("="*60)

运行结果

运行上述脚本,输出如下:

============================================================
Bugku CTF - MaybeEasyRSA 解题
============================================================

[步骤1] 对 n 开 10 次方, 得到 r 的近似值:
r_approx = 9876543209
n 的位数: 333 bit

[步骤2] 在 r_approx 附近搜索精确的 r 值:
搜索偏移量: 1
找到精确 r = 9876543210

[步骤3] 用 r = 9876543210 重建 p 和 q:
p1 = r^5 + r^4 - r^3 + r^2 - r + 2024
p = nextprime(p1) = 93977706209675566343917358829623734754104399311937
q1 = r^5 - r^4 + r^3 - r^2 + r + 2024
q = nextprime(q1) = 93977706190645080840549611028204535368410720892199
验证: p * q == n ? True

[步骤4] 利用欧拉定理 φ(n) = (p-1)(q-1) 计算私钥 d:
φ(n) = (p-1)*(q-1)
φ(n) 长度: 333 bit
d = e^(-1) mod φ(n)
d = 1402049888895502643198210053275818009609684150206960559578351272797398901847333840056414949259867649

[步骤5] RSA 解密: m = c^d mod n
m = 679536347117606377819503896328595943735431971467909561366942342218457469

[步骤6] 将明文 m 转为 bytes 得到 flag:
flag = b'bugku{Maybe_Easy_RSA_0r_Not?!}'

============================================================
Flag: bugku{Maybe_Easy_RSA_0r_Not?!}
============================================================

可以清晰地看到:从 n 开 10 次方得到 r_approx = 9876543209,仅偏移 1 就找到了精确的 r = 9876543210;重建 p 和 q 后验证 p*q == n 为 True;通过欧拉定理计算私钥 d,解密得到 flag。

总结

本题虽是 15 分的 Crypto 入门题,但涉及多个经典考点:

考点

说明

RSA基础原理

加密 c = m^e mod n,解密 m = c^d mod n,公私钥关系 ed ≡ 1 mod φ(n)

欧拉定理

φ(n) = (p-1)(q-1) 是 RSA 安全性的数学基石,也是解密的核心

nextprime特性

p ≈ p1、q ≈ q1,n ≈ r^10 的近似关系是本题突破口

开方近似

利用 n 的量级反推 r,从”分解 n”降维为”搜索 r”

大整数与字节串转换

使用 long_to_bytes 将解密后的整数还原为可读 flag

本题的核心启示是:RSA 的安全性不仅取决于密钥长度,更取决于素数的生成方式是否足够随机。一旦 p 和 q 的生成存在确定性结构(如本题由同一个 r 衍生),攻击者就能利用数学关系绕过分解难题。这也是为什么生产环境中必须使用密码学安全的随机数生成器(CSPRNG)来生成 RSA 素数对。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/9 1:04:37

健身行业同城引流,低投入高回报方案

健身房的流量&#xff0c;别再花在“烧钱刷曝光”上了 做健身的老板&#xff0c;你算过一笔账没&#xff1f;投了五万买同城流量&#xff0c;真正到店办卡的&#xff0c;也许就五个人。这不叫引流&#xff0c;这叫“用真金白银换了个寂寞”。 亲身踩过的坑。我自己的店&#…

作者头像 李华
网站建设 2026/7/9 1:03:28

2026教学设计PPT模板哪家强?教师/师范生首选(AI博主亲测)

一、前言相信很多教育行业的朋友都有这些痛点&#xff1a;普通商务PPT模板不适配教学设计固定框架&#xff1a;教学目标、学情分析、重难点、教学流程、教学反思板块全都没有网上免费模板杂乱&#xff0c;有水印、格式错乱、无法编辑母版师范生教资试讲、高校教师公开课&#x…

作者头像 李华
网站建设 2026/7/9 0:52:51

影刀RPA Excel条件格式与数据条自动设置:让报表一眼看出问题

影刀RPA Excel条件格式与数据条自动设置&#xff1a;让报表一眼看出问题 作者&#xff1a;林焱 采集完数据写入Excel只是第一步。如果一份销售报表&#xff0c;1000行数字密密麻麻&#xff0c;很难一眼看出哪个产品卖得好、哪个在掉队。条件格式&#xff08;Conditional Forma…

作者头像 李华
网站建设 2026/7/9 0:36:28

ADS1262与STM32F446ZE的高精度数据采集系统设计

1. 为什么需要弥合模拟与数字领域的鸿沟&#xff1f;在嵌入式系统开发中&#xff0c;模拟信号与数字信号的处理一直是个经典难题。我最近在一个工业传感器项目中&#xff0c;就深刻体会到了这种"跨界"处理的挑战。当时需要测量多路微伏级电压信号&#xff0c;同时还要…

作者头像 李华
网站建设 2026/7/9 0:28:25

3分钟找回经典B站:Bilibili-Old让你重拾简单纯粹的观看体验

3分钟找回经典B站&#xff1a;Bilibili-Old让你重拾简单纯粹的观看体验 【免费下载链接】Bilibili-Old 恢复旧版Bilibili页面&#xff0c;为了那些念旧的人。 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Old 还在为B站新版界面的复杂操作和缓慢加载而烦恼吗…

作者头像 李华