【CTF-CRYPTO-教学-RSA】第五节:9位数小 n 分解攻击
背景前面我们学的攻击手段共模攻击、dp 泄露都需要额外泄露一些信息才能下手。但现实里很多新手 RSA 题目根本不需要任何花活——只要 n 选得太小直接把 n 分解掉私钥就到手了。RSA 的安全性完全建立在大整数分解的困难性上公钥 (e, n) 是公开的n p × q只要攻击者能把 n 拆回 p 和 q就能算出 φ(n) (p-1)(q-1)有了 φ(n)私钥 d e⁻¹ mod φ(n) 就能直接算出来于是任意密文都能解密当 n 足够大如 2048 位时分解 n 在算力上不可行但当 n 很小如几十位、甚至 9~10 位十进制数时用最朴素的试除法就能秒分解。什么是逐字符加密及其弱点很多题目为了看起来密文很长会把明文的每一个字符单独加密得到一长串密文明文 flag → [加密(f), 加密(l), 加密(a), 加密(g)]这其实就是 RSA 的ECB 模式无填充它有两个致命弱点明文空间极小每个明文块只是一个字符ASCII 范围 32~126一共才 95 种可能。如果题目再提示只有数字和小写字母那明文只有 36 种可能。相同明文 → 相同密文没有随机填充同一个字符每次加密结果都一样。密文里只要出现重复值就说明明文里有重复字符泄露了模式。这两个弱点带来两种攻击姿势方法一分解 n把小 n 分解掉求出 d对每个密文m pow(c, d, n)解密再chr(m)还原字符。方法二暴力查表无需分解 n既然明文只有几十种可能干脆把每个候选字符 m 都加密一次c pow(m, e, n)建立c → m的反查表然后对着密文逐个反查即可。连 n 都不用分解当明文空间远小于密钥空间时加密变成了一个可逆的查表游戏——这正是无填充逐字符加密的悲哀。简单例子我们用p3, q11来演示数字小到可以在草稿纸上算完。生成密钥n p × q 3 × 11 33φ(n) (p-1)(q-1) 2 × 10 20选 e 3gcd(3, 20) 1 ✓公钥 (e, n) (3, 33)求私钥 d3 × d ≡ 1 (mod 20)3 × 7 21 20 1 ≡ 1 ✓所以d 7私钥 (d, n) (7, 33)逐字符加密为方便手算我们用字母表位置给明文编号a1, b2, c3, …要加密消息“cab”→ 明文序列 [3, 1, 2]加密公式 c mᵉ mod n m³ mod 33明文 m计算 m³ mod 33密文 c3 ( c )3³ 27271 ( a )1³ 112 ( b )2³ 88攻击者最终只看到n33, e3以及密文序列[27, 1, 8]。攻击一分解 n 求私钥n33 小到一眼可分33 3 × 11φ(n) (3-1)*(11-1)20e*d≡1 mod φ(n)推出 d 7解密 m cᵈ mod n c⁷ mod 33密文 2727 ≡ -6 (mod 33)(-6)² 36 ≡ 3(-6)⁴ ≡ 3² 9(-6)⁷ (-6)⁴ × (-6)² × (-6) 9 × 3 × (-6) -162 ≡ -162 5×33 3→ m 3 →‘c’密文 11⁷ 1 → m 1 →‘a’密文 88² 64 ≡ 64 - 33 318⁴ ≡ 31² 961 29×33 4 ≡ 48⁷ 8⁴ × 8² × 8 4 × 31 × 8 992 30×33 2 ≡ 2→ m 2 →‘b’恢复明文序列 [3, 1, 2] →“cab”✓ 闭环成功攻击二查表法不分解 n明文空间只有 az126共 26 种干脆全部加密一遍建反查表m1 → c1 m2 → c8 m3 → c27 ...拿到密文 [27, 1, 8] 直接反查27→3©、1→1(a)、8→2(b) →“cab”✓整个过程没有用到 p、q、d只用了公开的 e 和 n。可见逐字符无填充比n 太小还要致命——即使 n 大到分不动只要明文空间小查表法照样秒杀。代码实现# # RSA 小 n 分解 逐字符加密手算例子# ## 场景: p3, q11, n33, e3, d7# 明文用字母表位置 a1..z26 编码逐字符加密# 攻击:# 方法一: 分解 n33 → 求 d → 解密每个密文# 方法二: 暴力查表把 1..26 全加密一遍反查无需分解 n# deffactor_by_trial(n):试除法分解小 n返回 (p, q)i2whilei*in:ifn%i0:returni,n//i i1raiseValueError(n 是素数无法分解为两个 1 的因子)defmain():# ---- 公钥 ----n33e3# ---- 原始明文 cab用字母表位置编码 ----plaincabms[ord(ch)-96forchinplain]# a1, b2, c3print(f明文:{plain}- 明文序列{ms})# ---- 加密逐字符----cs[pow(m,e,n)forminms]print(f密文序列:{cs})print()# 方法一分解 n 求私钥 print( 方法一分解 n 求私钥 )p,qfactor_by_trial(n)print(f分解 n{n}{p}×{q})phi(p-1)*(q-1)dpow(e,-1,phi)print(fφ(n) {phi}, d {d})recovered1.join(chr(pow(c,d,n)96)forcincs)print(f解密结果:{recovered1})print()# 方法二暴力查表不分解 nprint( 方法二暴力查表不分解 n)table{pow(m,e,n):mforminrange(1,27)}# c - mrecovered2.join(chr(table[c]96)forcincs)print(f解密结果:{recovered2})if__name____main__:main()运行结果明文: cab -明文序列[3,1,2]密文序列:[27,1,8]方法一分解 n 求私钥分解n333×11φ(n)20, d7解密结果: cab方法二暴力查表不分解 n解密结果: cab作业RSA roll题目https://ctf2.dasctf.com/dashboard/practice/b9bbb32f-f186-458f-b90b-12440c0f6aea?tabchallengeschallenge542e42ea-2a5c-44c8-8801-9b30b7e1a973RSA rollrollroll Only number and a-z dont use editor which MS providedata.txt{920139713,19} 704796792 752211152 274704164 18414022 368270835 483295235 263072905 459788476 483295235 459788476 663551792 475206804 459788476 428313374 475206804 459788476 425392137 704796792 458265677 341524652 483295235 534149509 425392137 428313374 425392137 341524652 458265677 263072905 483295235 828509797 341524652 425392137 475206804 428313374 483295235 475206804 459788476 306220148解题过程第一步读懂题目格式{920139713, 19}就是公钥(n, e) (920139713, 19)下面一长串数字每行一个是密文序列逐字符加密的结果提示解读“Only number and a-z”flag 内容只含数字和小写字母 → 明文空间极小非常适合查表“roll roll roll”密文逐行滚动排列仔细看会发现有大量重复值如459788476出现了 6 次这正是无填充逐字符加密的指纹——同一个字符加密结果必然相同“don’t use editor which MS provide”暗示题目足够简单甚至不需要打开微软家的编辑器写复杂代码靠计算/查表即可拿下第二步观察密文规律把出现过的密文和它在序列里出现的次数统计一下会发现只有 17 种不同的密文对应 17 个不同字符而密文总数有 38 个——重复率极高坐实了逐字符无填充加密。第三步方法一 —— 分解 n 求私钥n 920139713 只有 9 位十进制用最朴素的试除法就能秒分920139713 18443 × 49891φ(n) (18443-1)(49891-1) 18442 × 49890 920071380d e⁻¹ mod φ(n) 19⁻¹ mod 920071380 96849619验证19 × 96849619 mod 920071380 1 ✓然后对每个密文m pow(c, d, n)再chr(m)还原字符。第四步方法二 —— 暴力查表无需分解 n明文只是可打印 ASCII数字、小写字母外加flag{}几个符号范围 32~126共 95 种。预计算c pow(m, e, n)for m in 32…126建c → m反查表再对 38 个密文逐个反查即可全程不需要 p、q、d。两种方法殊途同归得到同一段明文。具体实现代码# # 作业4: RSA roll —— 小 n 分解 逐字符加密# ## 已知: n920139713, e19, 以及一串逐字符加密的密文# 目标: 恢复明文 flag## 思路:# 方法一: n 只有 9 位试除法分解 → 求 d → 逐个解密 chr(pow(c,d,n))# 方法二: 明文空间极小把 32~126 全加密一遍建反查表逐个反查# deffactor_by_trial(n):试除法分解小 n返回 (p, q)i2whilei*in:ifn%i0:returni,n//i i1raiseValueError(n 是素数无法分解为两个 1 的因子)defmain():# ---- 题目参数 ----n920139713e19cs[704796792,752211152,274704164,18414022,368270835,483295235,263072905,459788476,483295235,459788476,663551792,475206804,459788476,428313374,475206804,459788476,425392137,704796792,458265677,341524652,483295235,534149509,425392137,428313374,425392137,341524652,458265677,263072905,483295235,828509797,341524652,425392137,475206804,428313374,483295235,475206804,459788476,306220148,]print( 作业4: RSA roll )print(f公钥 (n, e) ({n},{e}))print(f密文个数:{len(cs)}个不同密文:{len(set(cs))}种)print()# 方法一分解 n 求私钥 print( 方法一分解 n 求私钥 )p,qfactor_by_trial(n)print(f分解 n {p}×{q})print(f验证 p*q n ?{p*qn})phi(p-1)*(q-1)dpow(e,-1,phi)print(fφ(n) {phi})print(fd e^(-1) mod φ {d})print(f验证 (e*d) mod φ {(e*d)%phi})msg1.join(chr(pow(c,d,n))forcincs)print(f解密结果:{msg1})print()# 方法二暴力查表不分解 nprint( 方法二暴力查表不分解 n)table{pow(m,e,n):mforminrange(32,127)}# c - mmsg2.join(chr(table[c])forcincs)print(f解密结果:{msg2})print()# 顺带打印 密文 - 字符 映射 print( 出现过的 密文 - 字符 映射 )forcindict.fromkeys(cs):print(f{c}-{repr(chr(table[c]))})if__name____main__:main()运行结果作业4: RSA roll公钥(n, e)(920139713,19)密文个数:38个不同密文:17种方法一分解 n 求私钥分解 n18443×49891验证 p*qn ? True φ(n)920071380de^(-1)mod φ96849619验证(e*d)mod φ1解密结果: flag{13212je2ue28fy71w8u87y31r78eu1e2}方法二暴力查表不分解 n解密结果: flag{13212je2ue28fy71w8u87y31r78eu1e2}出现过的 密文 -字符 映射704796792-f752211152-l274704164-a18414022-g368270835-{483295235-1263072905-3459788476-2663551792-j475206804-e428313374-u425392137-8458265677-y341524652-7534149509-w828509797-r306220148-}答案flag{13212je2ue28fy71w8u87y31r78eu1e2}

相关新闻

终极指南:4步让老旧Mac免费升级到最新macOS系统

终极指南:4步让老旧Mac免费升级到最新macOS系统

终极指南:4步让老旧Mac免费升级到最新macOS系统 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否还在为苹果官方放弃支持的老旧Mac而烦恼&am…

2026/11/1 7:22:00 阅读更多 →
Codex+CC Switch如何进行基础配置详细指南

Codex+CC Switch如何进行基础配置详细指南

下载Codex与CC Switch Codex:https://openai.com/zh-Hans-CN/codex/ CC Switch:https://github.com/farion1231/cc-switch 一、CC Switch配置 1、安装后首先打开CC Switch 选择Codex后添加供应商 ​ 2、以Deepseek为例,找到供应商…

2026/10/24 2:25:33 阅读更多 →
Yole Group预测:车用半导体市场2031年将翻倍至1600亿美元

Yole Group预测:车用半导体市场2031年将翻倍至1600亿美元

Yole Group发布了《2026年汽车半导体趋势》报告,深入分析电气化、高级驾驶辅助系统、集中式计算架构及软件定义汽车等趋势如何重塑汽车半导体行业格局。报告预测,汽车半导体市场规模将从2025年的770亿美元增长至2031年的1600亿美元,复合年增长…

2026/10/28 11:29:14 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/1 0:24:43 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/31 10:20:19 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/31 10:20:23 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/1 1:06:58 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/31 10:30:19 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/31 9:29:43 阅读更多 →

日新闻

周新闻

月新闻