[NewStarCTF 2025 公开赛道] 初探Crypto:从古典密码到现代RSA实战解析

📅 2026/7/15 10:08:54
[NewStarCTF 2025 公开赛道] 初探Crypto:从古典密码到现代RSA实战解析
1. 古典密码从brainfuck到栅栏密码刚接触CTF密码学的新手最容易遇到的就是各种古典密码题目。这类题目通常不需要复杂的数学知识主要考察对编码规则的理解和工具使用能力。以NewStarCTF 2025第一周的题目为例我们先来看三种典型的古典密码。1.1 brainfuck符号背后的秘密第一道题目给出了一段由[]-.组成的奇怪代码[-].----.-----.-----.-----.-..........------.......-------.-...--..---.-.-...-------...这其实是brainfuck语言编写的程序。这种语言只有8种符号但能实现图灵完备的计算。实战中不需要手动解析使用在线解释器如https://www.splitbrain.org/services/ook直接运行就能得到flagflag{Oiiaioooooiai#b7c0b1866fe58e12}避坑指南遇到特殊符号时先考虑是否是已知的编码或编程语言。CTF中常见的还有Ook!、Malbolge等小众语言。1.2 凯撒密码字母的位移游戏第二题给出密文kqfl{hf3x4wx_h1umjw_n5_a4wd_3fed}观察花括号结构这显然是flag的变形。凯撒密码的特点是字母按固定位移替换使用CyberChef的ROT13工具尝试所有位移ROT3-ROT25发现ROT2时得到可读文本flag{ca3s4rs_c1pher_i5_v4ry_3azy}进阶技巧当密文包含数字和符号时可以编写Python脚本处理def caesar_decrypt(ciphertext, shift): result for char in ciphertext: if char.isalpha(): base ord(a) if char.islower() else ord(A) result chr((ord(char) - base - shift) % 26 base) else: result char return result1.3 栅栏密码文字的重新排列第三题密文fa{ereigtepanet6680}lgrodrn_h_litx#8fc3栅栏密码的特点是将明文按之字形排列后逐行读取。使用在线工具如https://www.boxentriq.com/code-breaking/rail-fence-cipher尝试不同栏数发现栏数为2时解密成功flag{reordering_the_plaintext#686f8c03}实战要点栅栏数通常为2-10密文长度是栅栏数的整数倍可以观察是否有规律间隔出现的字符如原题中f和l的间距2. 混合编码Base家族与UUencode现代CTF题目常将多种编码方式组合使用考察选手的编码识别能力。来看NewStarCTF的典型题目2.1 Base64/Base32混合编码题目给出三部分flagpart 1: ZmxhZ3tkYXp6bGluZ19lbmNvZGluZyM0ZTBhZDQ part 2: MYYGGYJQHBSDCZJRMQYGMMJQMMYGGN3BMZSTIMRSMZSWCNY part 3: 8S4U,3DR8SDY,CS-F5F-C(S,SR-CQ9F8S87T解题步骤第一部分明显是Base64以结尾的特征解码得到import base64 print(base64.b64decode(ZmxhZ3tkYXp6bGluZ19lbmNvZGluZyM0ZTBhZDQ)) # bflag{dazzling_encoding#4e0ad4第二部分长度是56字符符合Base32特征5的倍数print(base64.b32decode(MYYGGYJQHBSDCZJRMQYGMMJQMMYGGN3BMZSTIMRSMZSWCNY)) # bf0ca08d1e1d0f10c0c7afe422fea7第三部分包含,和等符号是UUencode特征from codecs import decode print(decode(8S4U,3DR8SDY,CS-F5F-C(S,SR-CQ9F8S87T, uu)) # bc55192c992036ef623372601ff3a最终组合得到完整flagflag{dazzling_encoding#4e0ad4f0ca08d1e1d0f10c0c7afe422fea7c55192c992036ef623372601ff3a}2.2 编码识别技巧编码类型特征常见结尾符Base64A-Za-z0-9/或Base32A-Z2-7序列UUencode首字符为M包含很多标点符号实用命令# Linux系统自带解码工具 echo Zm... | base64 -d echo MY... | base32 -d echo 8... | uudecode3. 现代密码学RSA实战突破RSA是CTF中最常见的非对称加密算法NewStarCTF 2025的babyrsa题目展示了典型场景3.1 基础RSA解密题目给出n 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261 e 65537 c 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595解题步骤使用factordb.com分解np 132086377753166933499766611941800337310934338951519 q 130972866061794536676655924442991410247854192126419计算私钥dfrom Crypto.Util.number import * phi (p-1)*(q-1) d inverse(e, phi)解密得到flagm pow(c,d,n) print(long_to_bytes(m)) # bflag{us4_s1ge_t0_cal_phI}3.2 Wiener攻击破解小d当私钥d很小时如题目中d是32位素数可以使用Wiener攻击def wiener_attack(e, n): # 连分数展开 def continued_frac(x, y): cf [] while y: cf.append(x // y) x, y y, x % y return cf # 渐进分数计算 def gradual_frac(cf): gf [] for i in range(1, len(cf)1): numerator 0 denominator 1 for x in cf[:i][::-1]: numerator, denominator denominator, x*denominator numerator gf.append((numerator, denominator)) return gf cf continued_frac(e, n) gf gradual_frac(cf) for d, k in gf: if d.bit_length() 32: # 已知d是32位 return d攻击原理当d (1/3)n^(1/4)时通过e/n的连分数展开可以快速恢复d。4. 对称密码实战从XOR到AES4.1 XOR加密破解题目给出密文e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2XOR加密的关键在于找到密钥这里采用已知明文攻击c bytes.fromhex(e9e3...) key c[0] ^ ord(f) # 假设flag以f开头 flag bytes([x ^ key for x in c]) # flag{x0r_15_symm3try_and_e4zy!!!!!!}4.2 AES-CBC模式攻击题目给出a 3657491768215750635844958060963805125333761387746954618540958489914964573229 c b]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i通过分析源码可知key是a的前16字节重复两次iv key[:16] ^ key[16:] ^ 1解密脚本key long_to_bytes(a)[:16] iv bytes_to_long(key) ^ bytes_to_long(long_to_bytes(a)[16:]) ^ 1 cipher AES.new(key*2, AES.MODE_CBC, long_to_bytes(iv)) print(cipher.decrypt(c)) # bflag{firsT_cry_Aes}\x00\x00\x00CBC模式要点需要正确的IV值填充错误可能导致解密失败可以通过修改IV实现位翻转攻击5. 仿射密码与维吉尼亚密码5.1 仿射密码解密题目密文dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064仿射加密公式c (a*p b) mod 256。通过已知明文建立方程# 已知flag头是f,l,a,g s Solver() a, b Int(a), Int(b) s.add(a * ord(f) b cipher[0]) s.add(a * ord(l) b cipher[1]) if s.check() sat: model s.model() a_val model[a].as_long() b_val model[b].as_long()解密得到flag{4ff1ne_c1pher_i5_very_3azy}5.2 维吉尼亚密码破解题目密文pqcq{qc_m1kt4_njn_5slp0b_lkyacx_gcdy1ud4_g3nv5x0}使用工具https://www.guballa.de/vigenere-solver自动分析发现密钥是kfcflag{la_c1fr4_del_5ign0r_giovan_batt1st4_b3ll5s0}破解技巧先确定密钥长度Kasiski测试对每组字母进行频率分析使用重合指数验证6. 实战工具链与学习路径6.1 必备工具推荐工具名称用途链接CyberChef各种编码/加密在线解密https://gchq.github.io/CyberChefRsaCtfToolRSA自动攻击工具https://github.com/Ganapati/RsaCtfToolXORToolXOR加密分析https://github.com/hellman/xortoolSageMath高级数学运算https://www.sagemath.org6.2 系统学习建议古典密码熟悉凯撒、栅栏、摩斯等传统密码掌握频率分析等基本技巧现代密码理解RSA、AES等算法数学原理学习常见攻击方式如选择密文攻击实战训练从CTFtime找适合新手的比赛定期刷Cryptohack.org的题目我在实际解题中发现密码学题目往往需要多次尝试。比如有一次遇到看似是Base64的字符串实际需要先进行字母替换才能正常解码。这种经验只能通过大量练习积累。