Ciphertexts - Writeup by AI

Ciphertexts - Writeup by AI

一、题目信息

  • 题目来源: Bugku CTF
  • 题目类别: Crypto / RSA
  • 题目文件 : main.py, output.txt
  • 考点: RSA 共模攻击、扩展欧几里得算法、数论

二、题目分析

2.1 代码逻辑

python 复制代码
p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
n1 = p * q          # 512+512 = 1024 位
n2 = p * q * r      # 512+512+512 = 1536 位

e1 = getPrime(20)
e2 = int(gmpy2.next_prime(e1))  # e2 是 e1 的下一个素数

m = bytes_to_long(flag)
c1 = pow(m, e1, n1)  # c1 = m^e1 mod n1
c2 = pow(m, e2, n2)  # c2 = m^e2 mod n2

2.2 关键特征

  1. 共享因子 : n2=n1×rn_2 = n_1 \times rn2=n1×r,即 n1∣n2n_1 | n_2n1∣n2
  2. 相邻指数 : gcd⁡(e1,e2)=1\gcd(e_1, e_2) = 1gcd(e1,e2)=1(相邻素数互质)
  3. 同一明文 : 使用相同的 mmm 进行两次加密

三、解题思路

3.1 核心观察

由于 n1∣n2n_1 | n_2n1∣n2,我们有:

  • c1≡me1(modn1)c_1 \equiv m^{e_1} \pmod{n_1}c1≡me1(modn1)
  • c2≡me2(modn2)  ⟹  c2≡me2(modn1)c_2 \equiv m^{e_2} \pmod{n_2} \implies c_2 \equiv m^{e_2} \pmod{n_1}c2≡me2(modn2)⟹c2≡me2(modn1)

因此在模 n1n_1n1 的意义下,我们有两个同余方程:
c1≡me1(modn1)c_1 \equiv m^{e_1} \pmod{n_1}c1≡me1(modn1)
c2≡me2(modn1)c_2 \equiv m^{e_2} \pmod{n_1}c2≡me2(modn1)

3.2 共模攻击

由于 gcd⁡(e1,e2)=1\gcd(e_1, e_2) = 1gcd(e1,e2)=1,根据扩展欧几里得算法,存在整数 a,ba, ba,b 使得:
a⋅e1+b⋅e2=1a \cdot e_1 + b \cdot e_2 = 1a⋅e1+b⋅e2=1

则:
m=ma⋅e1+b⋅e2=(me1)a⋅(me2)b≡c1a⋅c2b(modn1)m = m^{a \cdot e_1 + b \cdot e_2} = (m^{e_1})^a \cdot (m^{e_2})^b \equiv c_1^a \cdot c_2^b \pmod{n_1}m=ma⋅e1+b⋅e2=(me1)a⋅(me2)b≡c1a⋅c2b(modn1)

3.3 为什么可以恢复完整明文?

Flag 通常较短(几十字节),而 n1n_1n1 是 1024 位大整数,所以 m<n1m < n_1m<n1。因此通过上述方法计算出的 m(modn1)m \pmod{n_1}m(modn1) 就是 mmm 本身。

四、详细步骤

步骤 1: 验证 n2=n1×rn_2 = n_1 \times rn2=n1×r

python 复制代码
r = n2 // n1
assert n1 * r == n2  # 验证成立

计算得:

复制代码
r = 13153308347214004396487614747060422447697079642955901633441483325707932063710055895033655307701901587407685632388434170260760605433627022109576352718594963

步骤 2: 扩展欧几里得算法

计算 gcd⁡(e1,e2)\gcd(e_1, e_2)gcd(e1,e2) 和系数 a,ba, ba,b:

python 复制代码
g, a, b = gmpy2.gcdext(e1, e2)
# 结果:g = 1, a = -74571, b = 74570

验证:(−74571)×745699+74570×745709=1(-74571) \times 745699 + 74570 \times 745709 = 1(−74571)×745699+74570×745709=1 ✓

步骤 3: 计算明文 mmm

由于 a=−74571<0a = -74571 < 0a=−74571<0,需要计算 c1c_1c1 的模逆元:

python 复制代码
c1_inv = gmpy2.invert(c1, n1)
m = (c1_inv^(-a) * c2^b) mod n1

计算得:

复制代码
m = 110248894196938431401405464716666086561273237812093

步骤 4: 转换为字符串

python 复制代码
flag = long_to_bytes(m).decode('utf-8')
# 结果:KosenCTF{HALDYN_D0M3}

步骤 5: 验证

python 复制代码
# 验证 1: m^e1 mod n1 == c1
pow(m, e1, n1) == c1  # ✓

# 验证 2: m^e2 mod n2 == c2
pow(m, e2, n2) == c2  # ✓

五、完整代码

python 复制代码
from Crypto.Util.number import *
import gmpy2

# 题目数据
n1 = 112027309284322736696115076630869358886830492611271994068413296220031576824816689091198353617581184917157891542298780983841631012944437383240190256425846911754031739579394796766027697768621362079507428010157604918397365947923851153697186775709920404789709337797321337456802732146832010787682176518192133746223
n2 = 1473529742325407185540416487537612465189869383161838138383863033575293817135218553055973325857269118219041602971813973919025686562460789946104526983373925508272707933534592189732683735440805478222783605568274241084963090744480360993656587771778757461612919160894779254758334452854066521288673310419198851991819627662981573667076225459404009857983025927477176966111790347594575351184875653395185719233949213450894170078845932168528522589013379762955294754168074749
e1 = 745699
e2 = 745709
c1 = 23144512980313393199971544624329972186721085732480740903664101556117858633662296801717263237129746648060819811930636439097159566583505473503864453388951643914137969553861677535238877960113785606971825385842502989341317320369632728661117044930921328060672528860828028757389655254527181940980759142590884230818
c2 = 546013011162734662559915184213713993843903501723233626580722400821009012692777901667117697074744918447814864397339744069644165515483680946835825703647523401795417620543127115324648561766122111899196061720746026651004752859257192521244112089034703744265008136670806656381726132870556901919053331051306216646512080226785745719900361548565919274291246327457874683359783654084480603820243148644175296922326518199664119806889995281514238365234514624096689374009704546

# 计算 r
r = n2 // n1

# 扩展欧几里得算法
g, a, b = gmpy2.gcdext(e1, e2)

# 处理负指数,计算明文
if a < 0:
    c1_inv = gmpy2.invert(c1, n1)
    m = (pow(c1_inv, -a, n1) * pow(c2, b, n1)) % n1
elif b < 0:
    c2_inv = gmpy2.invert(c2, n1)
    m = (pow(c1, a, n1) * pow(c2_inv, -b, n1)) % n1
else:
    m = (pow(c1, a, n1) * pow(c2, b, n1)) % n1

# 转换为字符串
flag = long_to_bytes(m).decode('utf-8')
print(f"Flag: {flag}")

六、运行结果

复制代码
[*] Calculating r = n2 // n1...
[*] r = 13153308347214004396487614747060422447697079642955901633441483325707932063710055895033655307701901587407685632388434170260760605433627022109576352718594963
[+] Verified: n2 = n1 * r
[*] Computing extended GCD of e1 and e2...
[+] gcd(e1, e2) = 1, a = -74571, b = 74570
[*] Recovering message m...
[+] m mod n1 = 110248894196938431401405464716666086561273237812093
[+] Decoded flag: KosenCTF{XXX}
[+] Verification successful: m^e1 mod n1 == c1
[+] Verification successful: m^e2 mod n2 == c2
相关推荐
千里念行客2401 小时前
扬电科技落子“草原云谷”:一场算电协同的西部突围
大数据·人工智能·科技·安全
jinanwuhuaguo1 小时前
暗黑演化——记忆投毒、认知篡改与“数字精神分裂症”的安全悖论(第十四篇)
前端·人工智能·安全·重构·openclaw
麟飞扬2 小时前
麒麟系统安全基线检查与自动加固脚本
安全·系统安全·kylin·麒麟系统
其实防守也摸鱼2 小时前
软件安全与漏洞--实验 软件安全需求分析
网络·安全·网络安全·需求分析·法律·实验·软件安全与漏洞
littleM2 小时前
深度拆解 HermesAgent(七):CLI、安全与部署实践指南
人工智能·安全·架构
每天一把堆栈2 小时前
软件系统安全赛区域赛
安全·网络安全·pwn
深邃-2 小时前
【Web安全】-Kali,Linux配置(2):Java环境配置,Python环境配置,Conda使用,PIP配置使用,SSH远程登录
java·linux·python·安全·web安全·网络安全·php
wanhengidc2 小时前
云手机是什么黑科技?
运维·网络·科技·安全·web安全·智能手机
minji...2 小时前
Linux 线程同步与互斥(六) 线程安全与重入问题,死锁,线程done
linux·运维·开发语言·数据库·c++·算法·安全