CTF密码学入门:从编码到RSA攻击的实战解题框架

CTF密码学入门:从编码到RSA攻击的实战解题框架
1. 从解题到入门为什么你需要一份密码学总结如果你在CTF赛场上看到一段乱码或者一个奇怪的方程就头疼或者你刚入门网络安全觉得密码学深不可测那这篇文章就是为你准备的。我打CTF有年头了从最早看Base64都发懵到现在能快速识别和破解一些中低难度的密码学题目中间踩过的坑、浪费的时间足够写好几篇总结了。网上资料很多但要么太散要么一上来就讲复杂的数学原理对新手极不友好。所以我想做的就是把我这些年实战中最高频遇到、最核心的密码学知识点用最“人话”的方式串起来让你能快速建立一套可用的解题框架。密码学在CTF中尤其是入门和中级比赛中出场率极高。它不像Web渗透那样有那么多“骚操作”也不像逆向工程那样需要深厚的底层功底。密码学的题目很多时候考的是“见识”和“工具使用”。你知道这是什么编码、什么加密手边有合适的工具往往就能秒解如果不知道可能对着题目干瞪眼一晚上。这份总结的目的就是帮你扩充“见识库”并告诉你这些“见识”该怎么用。我们会从最基础的编码开始讲到古典密码、现代对称/非对称加密以及一些常见的攻击思路和技巧。我不会深入讲解RSA背后那复杂的数论证明但我会告诉你当你拿到一道RSA题时应该按什么步骤去分析、去尝试以及哪些工具能帮你省时省力。2. 密码学解题核心思路拆解面对一道密码学题目老手和新手的最大区别不在于懂得多少算法而在于有一套系统性的分析思路。新手容易陷入盲目尝试而老手则像医生问诊一样一步步缩小范围。2.1 第一步观察与信息收集CTF版“望闻问切”任何密码题都不会是孤零零给一串密文。你需要像侦探一样收集所有可能的信息。题目描述与标题这是最直接的提示。题目名可能就叫“凯撒的秘密”、“RSA签到”、“Base64没那么简单”。描述里可能包含“移位”、“密钥”、“flag格式”等关键词。附件内容如果提供了文件如.txt,.py,.pem一定要仔细查看。一个.pem文件可能直接包含了RSA的公钥或私钥一个.py脚本可能泄露了加密的逻辑或参数。密文特征这是判断编码或加密类型最直观的依据。仅由数字组成可能是十进制ASCII、坐标、或其他数字编码。仅由A-Z、a-z、0-9、、/和组成这几乎是Base64的“身份证”。注意是填充字符可能出现在末尾。仅由A-F、a-f、0-9组成典型的十六进制Hex编码。由%后跟两个十六进制数组成如%41这是URL编码。字符分布均匀无明显规律可能是AES、DES等现代分组加密的结果或者是经过多次编码/加密的套娃题。字符频率有规律英文文本可能是古典密码如凯撒、维吉尼亚、替换密码。可以用在线工具分析词频。包含花括号{}、flag字样有时出题人不会完全加密flag格式这可以作为已知明文攻击的突破口。上下文信息在Web题或杂项题中密码可能藏在HTTP响应头、图片注释、源代码注释、网络流量包中。注意第一步切忌直接上手就解密。花两三分钟做好信息收集能为你节省后面几十分钟甚至几小时的无效尝试。2.2 第二步分类与尝试从简单到复杂根据收集到的信息按照“编码 - 古典密码 - 现代密码”的优先级进行尝试。这个顺序是基于解题效率的解码通常最快古典密码次之现代密码需要更多分析。编码识别与解码这通常是第一道关卡。很多题目会把flag用Base64、Hex、URL、ASCII等编码进行多次转换即“套娃”。你需要一层层剥开。工具浏览器开发者工具Console、Python的base64、binascii库、CyberChef全能在线工具是必备的。技巧写一个简单的Python脚本进行循环解码直到出现可读文本是非常高效的方法。古典密码分析如果解码后得到的是像英文但读不懂的文本考虑古典密码。凯撒密码最简单暴力移位0-25即可。单表替换密码字符频率分析是王道。英文中e、t、a出现频率最高。使用quipqiup这类在线词频分析工具能极大提高效率。维吉尼亚密码首先需要确定密钥长度常用Kasiski测试法或重合指数法然后对每个分组进行频率分析猜解密钥。Vigenère Solver等自动化工具可以辅助。栅栏密码尝试不同的栏数。现代密码分析这需要更多密码学知识。对称加密AES, DES题目通常会给出加密脚本或提示加密模式。关键点在于密钥。密钥可能弱如短密码、常见单词可能被隐藏在别处或者加密模式不安全如ECB模式可能导致信息泄露。非对称加密RSA这是CTF密码学的重头戏。解题关键在于利用给出的条件如n,e,c,p,q,dp,dq等和已知的攻击方法如模数分解、共模攻击、低加密指数攻击、维纳攻击等。哈希与摘要MD5, SHA1通常不是让你破解哈希那是彩虹表的活而是考察哈希长度扩展攻击、哈希碰撞或是让你识别出已知的哈希值去在线网站反查。2.3 第三步工具化与脚本化不要重复造轮子也不要纯手工操作。成熟的CTF选手一定是“工具人”。离线工具Pythonpwntools/Crypto库是你的瑞士军刀。openssl命令行工具用于处理证书和加解密。RSACTFTool、RsaCtfTool等专门针对RSA攻击。在线工具CyberChef编码/加密/解码/解密全能厨房、quipqiup词频分析、factordb分解大整数、dcode.fr多种密码工具集合。脚本思想对于需要暴力破解、遍历、或者复杂计算的问题第一时间想到写脚本。比如暴力破解4位数字PIN码、遍历所有可能的栅栏数、尝试用不同的IV解密CBC模式。3. 核心密码类型详解与实战要点这一部分我们将深入几种CTF中最常见的密码类型不仅讲是什么更讲怎么考、怎么解。3.1 编码信息表示的“七十二变”编码不是加密它只是信息的不同表示形式通常没有密钥过程可逆。1. Base64出场率之王原理将每3个字节24位的数据重新划分为4组每组6位。这6位二进制数范围0-63对应一个字符映射表是A-Z、a-z、0-9、、/。末尾用填充。CTF考点单纯解码给一段Base64解码即可。CyberChef里丢进去就行。换表Base64出题人自定义一张64个字符的映射表。你需要从题目附件通常是加密脚本中找到这张表然后用它来解码。解题关键就是找到并替换标准Base64表。Base64隐写这是一个经典考点。Base64编码时末尾的填充位所对应的二进制数据有时会被忽略但一些工具会把这些“无效”位也存储起来。利用这些位可以隐藏信息。需要使用专门的工具如b64stegano或脚本来提取。实操命令# Linux命令行解码 echo “SGVsbG8gV29ybGQ” | base64 -d # Python解码 import base64 base64.b64decode(“SGVsbG8gV29ybGQ”)2. 十六进制Hex与URL编码Hex编码每个字节用两个0-9、a-f的字符表示。CyberChef中的From Hex操作即可。URL编码为了在URL中安全传输特殊字符将字符转换为%后跟其ASCII码的十六进制形式。例如空格是%20。在Web题中极为常见。考点通常作为一层简单的包装或者与其他编码/加密结合。注意区分大小写。3. 套娃编码这是新手最容易卡住的地方。题目可能将flag先进行Base64编码结果再进行Hex编码然后再进行URL编码……如此循环多次。解法手动一层层剥固然可以但更高效的是用CyberChef的魔法Magic功能。它能够自动检测并尝试多种编码组合。或者写一个Python脚本用try-except循环尝试常见的解码操作直到输出中包含flag或{等特征字符串。3.2 古典密码智慧与频率的博弈古典密码的安全性基于算法的保密性而非密钥。在现代计算机面前它们大多很脆弱。1. 凯撒密码移位密码原理将明文中的所有字母在字母表上向后或向前按照一个固定数目进行偏移。CTF考点纯凯撒题已经很少但常作为一部分出现。比如先凯撒移位再进行其他操作。工具任何古典密码工具都支持凯撒暴力破解。dcode.fr上的凯撒密码工具可以瞬间展示所有25种可能的结果。2. 单表替换密码原理建立一个明文字母到密文字母的一一映射表。比如所有a都替换成Q所有b替换成W。攻击方法——频率分析这是核心。英文中字母e的出现频率最高约12.7%其次是t,a,o,i,n等。双字母组合th,he,in,er等、三字母组合the,and,ing也有明显统计特征。实操心得不要试图完全手动分析。将密文粘贴到quipqiup.com它会自动进行频率分析并给出最可能的明文。你只需要根据上下文微调几个字母即可。如果密文较短频率特征不明显可以尝试结合题目描述或flag格式如flag{进行已知明文攻击推测出部分映射关系。3. 维吉尼亚密码原理使用一个关键词作为密钥对明文进行循环的凯撒移位加密。安全性比单表替换高很多。解题步骤确定密钥长度使用Kasiski测试寻找重复的密文片段计算其间距的公约数或计算重合指数Index of Coincidence, IC。在线工具可以自动完成这一步。分割密文根据密钥长度n将密文分成n组每组由被密钥中同一个字母加密的密文组成。频率分析每组此时每一组都是一个单表替换实际上是凯撒密码。对每一组进行频率分析猜解出密钥的对应字母。拼接密钥并解密。工具Vigenère Cipher Solver如guballa.de的版本可以一站式完成上述所有步骤是解决维吉尼亚题的利器。3.3 现代密码学核心RSA的常见攻击套路RSA题目千变万化但攻击方式相对固定。你需要像背公式一样熟悉以下几种场景。前置知识回顾n p * q大模数。e加密指数通常为65537。c密文c m^e mod n。φ(n) (p-1)*(q-1)欧拉函数。d私钥满足e*d ≡ 1 mod φ(n)。m明文m c^d mod n。攻击场景与工具场景一直接分解n条件n较小通常小于512位或p和q很接近。工具在线网站factordb.com。这是你的第一选择它有一个庞大的已分解数数据库。本地工具yafu强大的整数分解工具。命令如yafu “factor(n)”。Python库sympy的factorint函数适用于小整数。实操拿到n先扔factordb查一下。如果查不到且n不大再用yafu尝试分解。场景二共模攻击条件相同的n不同的e加密了同一明文m。原理如果gcd(e1, e2)1根据扩展欧几里得算法可以找到r和s使得e1*r e2*s 1。那么m (c1^r * c2^s) mod n。工具RsaCtfTool--attack common_modulus或自己写Python脚本实现扩展欧几里得算法。场景三低加密指数攻击如e3条件e很小如3且明文m满足m^e n。原理此时c m^e没有模运算直接对c开e次方即可得到m。扩展——广播攻击如果相同的低e加密了同一个明文m但发送给了kke个不同的接收者即有不同的n_i可以利用中国剩余定理CRT恢复m。工具RsaCtfTool--attack hastad或使用sage/Python的gmpy2库进行CRT计算。场景四维纳攻击条件私钥d相对n来说过小具体条件与e和n的位数有关。原理利用连分数逼近来从e和n中恢复出d。工具RsaCtfTool--attack wiener是首选。当e很大接近n时可以优先尝试此攻击。场景五已知dp, dq泄露条件给出了p,q,dp(d mod (p-1)),dq(d mod (q-1))但没有直接给d或φ(n)。原理利用中国剩余定理可以高效计算m c^d mod n。这是RSA-CRT的实现方式泄露这些参数同样危险。工具写脚本。公式是import gmpy2 # 假设已定义 p, q, dp, dq, c InvQ gmpy2.invert(q, p) # 计算q对p的模逆 m1 pow(c, dp, p) m2 pow(c, dq, q) h (InvQ * (m1 - m2)) % p m m2 h * q print(bytes.fromhex(hex(m)[2:]))场景六p和q相近Fermat分解条件p和q非常接近即|p-q|很小。原理令a (pq)/2,b (p-q)/2则n a^2 - b^2。由于b很小可以从a sqrt(n)开始尝试检查a^2 - n是否为完全平方数。工具RsaCtfTool--attack fermat或自己实现上述算法。重要心得拿到一道RSA题首先把所有给出的参数n, e, c, p, q, dp, dq, ...整理出来。然后对照上述场景看符合哪个条件。优先尝试factordb分解n如果不行再根据e的大小、参数组合来判断可能适用的攻击方法。RsaCtfTool是一个集大成的工具支持--attack指定多种攻击模式通常能解决大部分常规题。4. 实战流程与工具链配置理论说再多不如实际走一遍。这里我以一个虚构的、但融合了常见考点的“套娃题”为例展示完整的解题流程。4.1 题目假设与初始分析我们收到一个文件challenge.txt内容如下题目找到真正的flag。 密文U2FsdGVkX1%2B9L%2F7%2F8J%2BqKjJd%2FkzWp%2FmN%2FZ%2F%2Bv%2F7f3t%2Fe397f3 提示1不止一层。 提示2与“salted”有关。第一步观察与信息收集密文包含大量%符号这是明显的URL编码特征。提示“不止一层”说明是多重编码/加密。提示“与‘salted’有关”。在密码学中“Salted”经常出现在OpenSSL加密的标识中。U2FsdGVkX1是OpenSSL使用Salted__作为魔数并进行Base64编码后的固定开头。第二步分类与尝试第一层URL解码。使用CyberChef添加URL Decode模块。解码后得到U2FsdGVkX19L/7/8JqKjJd/kzWp/mN/Z/v/7f3t/e397f3可以看到%2B解码成了%2F解码成了/。现在字符串由B64字符集和、/组成。第二层Base64解码。在CyberChef中接着添加From Base64模块。注意这里的和/是标准Base64字符。解码后得到一串看起来像乱码的二进制数据。CyberChef可能会将其显示为Hex。分析结果解码后的数据其开头部分在Hex视图下可能是Salted__的ASCII码53616c7465645f5f。这验证了提示2。这表明数据是经过OpenSSL加密的格式通常是Salted__(8字节) 盐值(8字节) 密文。第三层OpenSSL解密。现在我们需要知道加密算法和密码。题目没有直接给。常见的考察点是AES-256-CBC或DES。密码口令可能是弱密码如password、123456、flag或者藏在题目其他地方如图片、注释。这里我们假设密码是弱密码password。工具选择可以使用OpenSSL命令行但CyberChef更方便。CyberChef操作添加Decrypt模块选择AES Decrypt。模式选CBC。输入密码password。因为数据包含盐值所以IV参数通常留空工具会自动从输入数据头部提取盐值并推导IV。点击执行。尝试如果AES-256-CBC不行尝试AES-128-CBC、DES等。如果密码不对需要结合其他线索或进行简单的字典爆破可以用John the Ripper或hashcat但本题假设密码已知。假设我们使用AES-256-CBC和密码password解密成功输出是一段可读文本flag_is_here{Base64_Url_And_Openssl_AES}4.2 工具链配置建议一个高效的环境能让你事半功倍。浏览器书签CyberChef:https://gchq.github.io/CyberChef/quipqiup词频分析:https://www.quipqiup.com/dCode多种密码工具:https://www.dcode.fr/enFactoDB因数分解:http://factordb.com/本地Python环境安装pwntoolsCTF全能库处理网络交互、数据打包解包非常方便。安装pycryptodome或cryptography提供标准的加密算法实现。安装gmpy2用于大整数运算解RSA题必备。安装sympy用于数学计算和分解小整数。专用工具RsaCtfTool(GitHub): 集成了绝大多数RSA攻击脚本命令行调用非常强大。John the Ripperhashcat密码破解神器对于弱密钥、哈希碰撞等题目有用。WiresharkNetworkMiner分析流量包中的密码数据。脚本模板准备一些常用的Python脚本模板比如Base64/Hex循环解码、简单凯撒/栅栏暴力、RSA共模/低指数攻击脚本。比赛时直接修改参数就能用。5. 常见问题与排查技巧实录即使知道了方法实战中还是会遇到各种奇怪的问题。这里记录一些我踩过的坑和解决技巧。问题1Base64解码报错“Incorrect padding”。原因Base64字符串的长度必须是4的倍数且填充符的位置和数量可能被破坏或移除。解决首先检查字符串长度。如果不是4的倍数尝试在末尾补上1或2个。有时出题人会去掉。你可以手动补上或者使用Python的base64.b64decode(cipher ‘’)并捕获异常尝试补一个或两个。使用base64.urlsafe_b64decode它处理-和_替换和/的情况。终极方法使用base64.b64decode(cipher, validateFalse)但这不是标准做法可能解码出错误数据。问题2古典密码词频分析工具给了结果但看起来还是不对。原因密文太短统计特征不明显。明文不是标准英文可能是技术术语、flag格式或其他语言。工具猜错了几个关键字母。解决利用已知明文CTF的flag通常有固定格式如flag{、ctf{、SECCON{。将密文中对应位置的字母强制替换为已知明文然后让工具基于此重新分析。手动微调工具给出的结果通常接近80%正确。仔细阅读输出根据英文单词的构成如th、ing、tion常见手动修正几个字母可能就全通了。尝试其他工具不同的词频分析工具可能使用不同的字典或算法换一个试试如dcode.fr的替换密码求解器。问题3RSA题目给了n和e用factordb分解不了yafu也跑不出来。排查思路检查n的长度如果n超过1024位常规分解在比赛时间内可能不现实需要考虑其他攻击路径。检查e的大小如果e非常大接近n思考维纳攻击。如果e非常小如3, 17思考低加密指数攻击或广播攻击。检查是否有多组n、e、c如果有两组以上的数据考虑共模攻击或广播攻击。检查是否给了其他参数仔细阅读题目看是否附件中隐藏了p、q、dp、dq、hint等文件。dp、dq泄露是常见考点。检查n是否有特殊性质用python检查gcd(n1, n2)看多个n之间是否有公因数。或者检查n是否是素数gmpy2.is_prime有些题会直接给pn。搜索已知的n有时出题人会复用以前题目用过的n或者使用一些著名的、已被分解的RSA数字如RSA-768。可以尝试用n的十进制或十六进制值去搜索引擎或CTF社区搜索。问题4使用工具解密AES/DES时输出仍是乱码。可能原因密码错误这是最常见的原因。回顾题目所有描述、注释、文件名、其他附件寻找可能的密码。尝试空密码、password、123456、flag、key等弱密码。加密算法或模式错误AES还分ECB、CBC、CFB等模式。如果模式不对解密会失败。题目脚本通常会写明如AES.MODE_CBC。如果没有CBC是最常见的。IV初始化向量错误CBC模式需要IV。如果加密时IV是随机的并放在密文前解密时需要正确提取。如果IV是全零或与密钥相关题目可能会暗示。数据格式问题确保你提供给解密函数的数据是原始的字节串bytes而不是经过Hex或Base64编码的字符串。在CyberChef中要注意模块之间数据格式的衔接是Raw还是Hex。问题5题目说是“逗号隐写”或“零宽字符隐写”。逗号隐写通常指在文本中利用中文全角逗号“”和英文半角逗号“,”的差异或者逗号数量的差异来隐藏二进制信息如摩斯电码。你需要将不同的逗号映射为0和1。零宽字符隐写这是一种在网页或文本中插入不可见Unicode字符如零宽空格、零宽连接符等来隐藏信息的方法。解决将文本复制到一个能显示所有字符的编辑器如VS Code并开启“渲染空白字符”功能。对于逗号隐写写脚本统计并转换。对于零宽字符可以使用在线解码工具搜索“zero width character decoder”或Python库zlib配合特定算法提取。最后也是最重要的心得保持耐心和条理。密码学题目有时就像解谜信息可能分散在各处。把所有线索写在草稿纸上一步步推导。当一种思路卡住超过15分钟时果断跳出来重新审题或者换一种攻击假设。多打比赛多复盘别人的Writeup你的“武器库”和“条件反射”会越来越丰富。这套总结是一个起点希望能帮你推开CTF密码学这扇门后面的路还需要你在实战中不断积累和探索。