CTF实战:从爱情故事中破解AES-CBC加密的Python脚本详解

发布时间:2026/7/27 20:16:31

CTF实战:从爱情故事中破解AES-CBC加密的Python脚本详解
1. 项目概述一次别开生面的CTF实战复盘最近在CTFshow平台的一场水友赛中遇到了一道非常有意思的题目。它没有直接给你一个冷冰冰的加密文件或一串十六进制密文而是将一道AES加密的挑战巧妙地包装在一个“爱情故事”的叙事里。这种出题方式不仅考验你的密码学知识更考验你从复杂场景中提取关键信息、还原加密逻辑的能力。对于很多刚接触CTFCapture The Flag安全竞赛的朋友来说密码学题目往往是最让人头疼的部分尤其是像AES高级加密标准这种涉及模式、密钥、初始向量的对称加密算法光是概念就够绕一阵子了。但这次我们换个角度不从枯燥的理论出发而是跟着这个“爱情故事”的线索一步步拆解看看如何用Python脚本这把“手术刀”精准地剖开加密的外壳拿到最终的Flag。无论你是CTF新手想入门密码学还是对Python在安全领域的应用感兴趣这篇复盘都能给你带来一次完整的、可复现的实战体验。2. 核心思路拆解从故事到加密逻辑的映射面对这类叙事型题目第一步也是最关键的一步就是“阅读理解”。出题人不会无缘无故地讲一个故事故事里的每一个细节都可能对应着加密算法的一个参数或一个步骤。2.1 故事场景与密码学元素的对应关系通常这类故事会包含几个核心要素通信的双方比如故事里的“小明”和“小红”。这往往对应加密中的发送方和接收方。在AES加密中这意味着存在一个加密过程和一个对应的解密过程。传递的“信物”或“暗号”这就是被加密的原始信息明文和我们最终要获取的Flag。约定的“规则”或“密码本”这直接指向加密算法AES和其工作模式如CBC、ECB。故事里可能会用“只有我们俩懂的方式”、“按照上次说好的顺序”等来描述。“钥匙”或“秘密”这是加解密的核心——密钥Key。故事可能把它藏在某句情话的首字母里、一段特定文字的MD5值里或者一个约定的数字里。“起始的约定”在AES的CBC等模式中需要一个初始向量IV来让每个块的加密结果都不同。故事里可能会用“从我们第一次见面的日子开始算”、“以那天约定的暗号开头”来暗示。复盘时我的做法是拿出一张纸把故事段落拆开逐句分析将上述可能对应的密码学元素标注在旁边。比如故事提到“他们用彼此生日组合成的16位数字作为秘密”这极有可能就是密钥又说“每封信的开头都要加上第一次约会的时间戳”这很可能就是IV。2.2 常见AES出题套路与本题关联在CTF的AES题目中有几个高频考点密钥泄露密钥以某种形式直接给出或隐含在题目描述、附件、网页源码中。IV相关攻击当IV可预测、重复使用或与密钥相关时可能引发攻击如CBC模式的字节翻转攻击。模式误用例如使用ECB模式导致相同明文块产生相同密文块可以通过模式识别来破解。Padding Oracle攻击当服务器或题目提供的解密接口会返回填充是否正确这类错误信息时可以利用此漏洞逐字节解密。结合“爱情故事”的包装本题很可能属于前两种即密钥和IV都以一种需要“解读”的方式隐藏在叙事中。我们的任务就是扮演侦探从故事文本里提取出这些参数。2.3 解题工具箱的选择为什么是Python在CTF中密码学题目的求解几乎离不开编程。Python因其丰富的库和简洁的语法成为首选。对于AES我们主要依赖cryptography库或pycryptodome库。两者功能都很强大pycryptodome在CTF社区中更流行因为它对很多加密原语的支持非常直接API也更贴近我们的操作习惯。本文将使用pycryptodome进行演示。选择Python脚本的另一个好处是可复现和可调试你可以随时打印中间变量观察数据流转这对于理解加密过程和排查错误至关重要。3. 实战步骤详解还原破解全过程假设我们从题目中获得了以下核心信息为保护原题此处为模拟场景故事梗概小明和小红约定用他们第一次相遇的日期“2023-05-21”的MD5值的前16位作为密钥用“forever”的SHA256哈希值的前16位作为每封信的起始向量IV采用AES-CBC模式加密他们的情书。最后小红给了小明一段Base64编码的密文说答案就在里面。下面我们一步步用Python实现破解。3.1 环境准备与依赖安装首先确保你的Python环境3.6以上均可已经就绪。打开终端或命令提示符安装必要的库pip install pycryptodome这个命令会安装Crypto模块它包含了我们需要的所有密码学工具。注意在有些系统上可能会因为与旧的pycrypto库冲突而安装失败。如果遇到问题可以尝试使用pip install pycryptodome --upgrade或者在一个干净的虚拟环境中安装。3.2 关键信息提取与参数计算根据故事我们需要计算两个关键参数密钥Key“2023-05-21”的MD5值的前16位16字节。初始向量IV“forever”的SHA256值的前16位16字节。AES-128-CBC模式正好需要16字节的密钥和16字节的IV。from Crypto.Hash import MD5, SHA256 import base64 # 1. 计算密钥 meeting_date “2023-05-21” md5_hash MD5.new(meeting_date.encode(‘utf-8’)).hexdigest() # 得到32位十六进制字符串 key_hex md5_hash[:32] # 取前32个十六进制字符即16字节 key bytes.fromhex(key_hex) # 转换为字节串 print(f“密钥Keyhex: {key_hex}”) print(f“密钥Keybytes: {key}”) # 2. 计算初始向量IV secret_word “forever” sha256_hash SHA256.new(secret_word.encode(‘utf-8’)).hexdigest() iv_hex sha256_hash[:32] # 同样取前32个十六进制字符即16字节 iv bytes.fromhex(iv_hex) print(f“初始向量IVhex: {iv_hex}”) print(f“初始向量IVbytes: {iv}”)执行这段代码你会得到具体的密钥和IV值。这一步是整个解密的基础务必确保计算准确。一个常见的坑是字符串编码必须统一使用utf-8进行.encode()操作。3.3 密文处理与AES-CBC解密假设我们从题目中得到的Base64密文是“9Y8l2fF6x7pCqRgTz1XyM4bNcV8aS3DdE0oLhKjPwQvAmFuH5iGtBcZrWeLkOxYI”此为示例非真实密文。解密流程如下将Base64密文解码为字节串。使用上面计算出的key和iv创建AES解密器。执行解密。处理解密后的明文可能存在的填充Padding。AES-CBC通常使用PKCS7填充。from Crypto.Cipher import AES # 假设的Base64密文 ciphertext_b64 “9Y8l2fF6x7pCqRgTz1XyM4bNcV8aS3DdE0oLhKjPwQvAmFuH5iGtBcZrWeLkOxYI” # 1. Base64解码 ciphertext_bytes base64.b64decode(ciphertext_b64) print(f“密文长度: {len(ciphertext_bytes)} 字节”) # 2. 创建AES-CBC解密器 cipher AES.new(key, AES.MODE_CBC, iv) # 3. 解密 padded_plaintext cipher.decrypt(ciphertext_bytes) # 4. 去除PKCS7填充 # PKCS7填充规则填充的每个字节的值等于填充的字节数 pad_len padded_plaintext[-1] # 取最后一个字节的值 # 验证填充是否合法 if pad_len 1 or pad_len AES.block_size: # AES块大小为16字节 raise ValueError(“Invalid padding length.”) if padded_plaintext[-pad_len:] ! bytes([pad_len]) * pad_len: raise ValueError(“Invalid padding bytes.”) # 去除填充 plaintext padded_plaintext[:-pad_len] print(f“解密后的明文: {plaintext.decode(‘utf-8’)}”)3.4 整合脚本与Flag提取将以上步骤整合成一个完整的Python脚本并增加一些健壮性处理和错误提示是CTF中的好习惯。#!/usr/bin/env python3 # -*- coding: utf-8 -*- import base64 from Crypto.Cipher import AES from Crypto.Hash import MD5, SHA256 from Crypto.Util.Padding import unpad # 使用库自带的去填充函数更安全 def decrypt_love_letter(ciphertext_b64, date_str, iv_str): “”” 根据爱情故事约定解密信息 :param ciphertext_b64: Base64编码的密文 :param date_str: 用于生成密钥的日期字符串 :param iv_str: 用于生成IV的字符串 :return: 解密后的明文 “”” try: # 1. 计算密钥和IV key bytes.fromhex(MD5.new(date_str.encode()).hexdigest()[:32]) iv bytes.fromhex(SHA256.new(iv_str.encode()).hexdigest()[:32]) print(f“[] 密钥: {key.hex()}”) print(f“[] 初始向量: {iv.hex()}”) # 2. 解码并解密 ciphertext base64.b64decode(ciphertext_b64) cipher AES.new(key, AES.MODE_CBC, iv) padded_plaintext cipher.decrypt(ciphertext) # 3. 去除填充 (使用Crypto库自带的unpad避免手动实现错误) plaintext unpad(padded_plaintext, AES.block_size) return plaintext.decode(‘utf-8’) except Exception as e: return f“[-] 解密失败: {e}” if __name__ “__main__”: # 这里是题目给的具体数据 encrypted_message “替换为实际的Base64密文” key_seed “2023-05-21” iv_seed “forever” result decrypt_love_letter(encrypted_message, key_seed, iv_seed) print(f“[] 解密结果: {result}”) # 通常Flag格式为 ctfshow{xxx}可以在结果中查找 if “ctfshow{” in result: print(f“[] 发现Flag: {result[result.find(‘ctfshow{‘):]})运行这个脚本如果一切参数正确你就能在输出中看到包含Flag的明文。Flag很可能被包裹在ctfshow{...}的格式中。4. 深度原理剖析AES-CBC模式为何这样工作仅仅会运行脚本还不够理解背后的原理能让你举一反三应对更复杂的变化。4.1 AES算法与CBC模式核心机制AES是一种分组密码一次处理一个固定长度128位即16字节的数据块。CBC密码分组链接模式则是为了解决ECB模式中相同明文块产生相同密文块的安全缺陷而设计的。它的核心过程如下加密端第一个明文块先与初始向量IV进行异或XOR操作。将结果用AES算法和密钥进行加密得到第一个密文块。下一个明文块不再与IV异或而是与前一个密文块进行异或然后再加密。如此重复直到所有明文块处理完毕。解密端用密钥解密第一个密文块得到一个中间值。将这个中间值与IV进行异或得到第一个明文块。解密下一个密文块得到中间值将其与前一个密文块异或得到下一个明文块。如此重复。从这个流程可以清晰看到IV参与了第一个块的解密运算。如果解密时使用的IV与加密时不同得到的第一个明文块将是错误的但由于CBC的链式特性这个错误只会影响第一个块后面的块解密依然正确但可能因为错误传播而变得乱码。这在CTF中有时会成为提示。4.2 填充Padding的必要性与PKCS7因为AES处理固定大小的块如果明文长度不是16字节的整数倍就需要在末尾进行填充使其达到块长度的倍数。PKCS7是一种最常用的填充方案。如果块长度是16字节需要填充N个字节那么这N个字节的值就都等于N。例如明文差3字节满块就填充0x03 0x03 0x03。解密后我们需要根据最后一个字节的值移除相应数量的填充字节。这就是上面脚本中unpad函数所做的工作。如果填充验证失败通常意味着密钥、IV或密文有误这是调试时一个重要的错误信号。4.3 从故事到参数的思维转换为什么出题人喜欢用故事因为它增加了信息隐藏的维度和干扰项。你可能需要从一段抒情文字里精准地挑出那几个有特殊含义的单词或数字。这要求解题者熟悉常见编码和哈希如Base64、Hex、MD5、SHA1、SHA256等它们常被用来处理原始字符串。了解常见密钥/IV生成方式直接字符串、字符串的哈希、数字的字符串形式、特定偏移量的字符等。注意数据格式密钥和IV通常是16、24、32字节对应AES-128, AES-192, AES-256提取的十六进制字符串长度对应为32、48、64字符。5. 常见问题与实战调试技巧在实际操作中很少能一次成功。下面是一些我踩过坑后总结的排查经验。5.1 问题排查清单当你运行脚本后没有得到预期的Flag可以按照以下顺序检查问题现象可能原因排查方法UnicodeDecodeError或解密后是乱码1. 密钥/IV错误。2. 密文错误或被篡改。3. 加密模式不是CBC可能是ECB, CFB等。1. 打印并核对密钥/IV的十六进制值与手动计算或题目暗示核对。2. 确认Base64密文是否完整有无换行、空格。3. 尝试其他常见模式需修改脚本。ValueError: Invalid padding1. 密钥/IV错误导致解密出的填充值非法。2. 密文长度不是块大小的整数倍。3. 实际使用的填充方式不是PKCS7。1. 同上优先检查密钥/IV。2. 检查len(ciphertext_bytes) % 16是否为0。3. 尝试不使用unpad直接输出解密后的字节看末尾是否有规律字符如多个\x01,\x02或尝试其他填充方式如ZeroPadding。解密出的明文开头几个字符是乱码后面正常IV错误。在CBC模式中错误的IV只会影响第一个明文块。重点检查IV的生成逻辑。确认故事中关于“起始”的描述是否理解有误。脚本报错ModuleNotFoundError: No module named ‘Crypto’pycryptodome库未正确安装或导入。确认安装命令是pip install pycryptodome。在代码中尝试import Cryptodome并查看其路径。有时需要pip uninstall pycrypto再安装pycryptodome。5.2 高级调试技巧“盲解”与模式探测如果完全不知道模式可以写一个循环用同一份密钥和密文尝试AES.MODE_CBC、AES.MODE_ECB、AES.MODE_CFB等常见模式观察输出中是否有可读字符串。暴力破解弱密钥如果故事中暗示密钥范围很小比如生日组合只有几种可能可以编写脚本暴力枚举所有可能的密钥。利用错误信息如果题目提供了一个“解密服务”并返回填充正确与否的错误那很可能是一道Padding Oracle攻击题需要完全不同的攻击脚本。关注非打印字符解密出的明文可能是二进制数据包含不可打印字符。使用repr(plaintext)打印转义后的形式或者用plaintext.hex()查看十六进制可能发现隐藏的Flag或下一步的提示。编码陷阱确保所有字符串到字节的转换编码一致通常UTF-8。有时题目会用ASCII、Latin-1甚至UTF-16。5.3 针对本题“爱情故事”类型的特别建议多读几遍故事出题人的幽默感或双关语可能藏在字里行间。“永恒的爱”可能指“forever”但也可能指“eternity”或“always”。注意数字和日期任何出现的数字都可能被直接用作密钥、IV的一部分或者作为某种计算的索引如取字符串的第N个字符。尝试所有可能的组合如果故事提到“名字的组合”可能是拼接也可能是交错或者取其ASCII码值。用脚本快速尝试几种合理的组合方式比人脑穷举高效得多。最后把这次解题过程整理成一个通用的Python脚本模板以后遇到类似的“故事型”AES题目你只需要修改信息提取和参数计算的那部分逻辑就能快速套用。密码学解题就像拼图而Python是你手中最灵活的镊子能帮你精准地拿起并安放每一块拼图。真正的乐趣就在于从看似杂乱的故事碎片里还原出那个严谨而美妙的加密逻辑。

相关新闻

LM3S1968定时器与看门狗寄存器级配置实战指南

LM3S1968定时器与看门狗寄存器级配置实战指南

2026/7/27 20:16:31

1. 项目概述与核心价值在嵌入式开发领域,尤其是基于ARM Cortex-M内核的微控制器应用,定时器和看门狗是两个你绕不开的核心外设。它们一个负责精准的“心跳”和“节拍”,另一个则扮演着系统“守护神”的角色。今天,我们就来深入聊聊…

IDEA算法与位平面分解的图像加密技术详解

IDEA算法与位平面分解的图像加密技术详解

2026/7/27 20:16:30

1. 项目背景与核心思路在数字图像安全传输领域,位平面加密技术因其独特的细粒度控制能力而备受关注。这个方案将国际数据加密算法(IDEA)与图像位平面分解技术相结合,实现了像素级的安全防护。不同于传统的整体加密方式&#xff0c…

赛车游戏物理同步:权威服务端与客户端预测架构实战解析

赛车游戏物理同步:权威服务端与客户端预测架构实战解析

2026/7/27 20:06:30

1. 项目概述:为什么赛车游戏的物理同步是“硬骨头”?做过多款赛车游戏的老鸟都知道,物理同步是这类项目里最让人头疼、也最核心的技术挑战。你花了大把时间调校出丝滑的漂移手感、真实的悬挂反馈和精准的碰撞响应,结果一到多人联机…

iOS应用安装终极指南:5分钟掌握App Installer安装第三方应用

iOS应用安装终极指南:5分钟掌握App Installer安装第三方应用

2026/7/28 1:06:57

iOS应用安装终极指南:5分钟掌握App Installer安装第三方应用 【免费下载链接】App-Installer On-device IPA installer 项目地址: https://gitcode.com/gh_mirrors/ap/App-Installer App Installer是一款功能强大的iOS应用安装工具,让你无需通过A…

番茄小说下载器完全指南:3分钟建立你的个人数字图书馆

番茄小说下载器完全指南:3分钟建立你的个人数字图书馆

2026/7/28 1:06:57

番茄小说下载器完全指南:3分钟建立你的个人数字图书馆 【免费下载链接】fanqienovel-downloader 下载番茄小说 项目地址: https://gitcode.com/gh_mirrors/fa/fanqienovel-downloader 你是否曾经遇到过这样的情况:收藏的番茄小说突然下架&#xf…

英雄联盟智能助手:5分钟掌握本地化游戏效率工具

英雄联盟智能助手:5分钟掌握本地化游戏效率工具

2026/7/28 1:06:57

英雄联盟智能助手:5分钟掌握本地化游戏效率工具 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akari 是一款基于英雄联盟客…

Audio Slicer:告别手动剪辑的智能音频分割解决方案

Audio Slicer:告别手动剪辑的智能音频分割解决方案

2026/7/28 1:06:57

Audio Slicer:告别手动剪辑的智能音频分割解决方案 【免费下载链接】audio-slicer A simple GUI application that slices audio with silence detection 项目地址: https://gitcode.com/gh_mirrors/aud/audio-slicer 还在为繁琐的音频剪辑工作而烦恼吗&…

现在的你只能解决现在水平的问题

现在的你只能解决现在水平的问题

2026/7/28 1:06:57

人的能力边界,决定了当前能处理的问题范围。你今天遇到的问题,往往刚好暴露了你当前能力系统的边界。这句话不是限制你。 恰恰相反: 它解释了: 为什么解决问题会让人成长。第一层:问题的难度匹配你的能力水平 人的成长…

别再让AI乱改Flutter代码!我总结了一套边界管控方案

别再让AI乱改Flutter代码!我总结了一套边界管控方案

2026/7/28 0:56:57

文章目录一、现在AI写Flutter代码跟脱缰野马一样1.1 代码跑偏四大经典社死现场二、全套约束方案,专治AI乱改代码2.1 双层规则文件,给模型画死红线2.1.1 AGENTS.md:项目通用底线,不超50行2.1.2 .cursor/rules/拆分规则文件&#xf…

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

2026/7/27 8:45:59

目标:电脑作为RTSP 服务端,循环推送 H264/H265 视频流; RDK X5 通过 rtsp2display 拉流预览,完全不需要在开发板编译 live555。 提供两套成熟方案: ✅ 方案 A:FFmpeg(最简单,优先推…

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

2026/7/27 8:42:17

一、背景与测试方案 在实际项目交付中,PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及:多源PDF的文件流合并、页面级水印渲染(含透明度混合与图层叠加)、输出文件体积控制。看似简单的操作…

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

2026/7/27 14:56:57

说实话,提到PDF拆分再压缩,我真是被折腾得够呛。 上个月公司年度合同归档,一份300多页的PDF总合同,需要按年份拆分成三个独立文件,再分别压缩到10MB以内方便邮件发送各部门确认。我心想这还不简单?先找个海…

零基础搭建桌面智能体,OpenClaw 2.7.9 分步实操,避开绝大多数部署陷阱

零基础搭建桌面智能体,OpenClaw 2.7.9 分步实操,避开绝大多数部署陷阱

2026/7/28 0:06:55

📌 一、工具核心优势盘点 数据本地存储,安全系数高所有操作日志、文档资料均保存在本机,不会上传至云端,能够有效保护企业文件与个人隐私,规避数据泄露风险。 上手简单,零编程门槛采用全图形化可视化界面&…

计算机毕业设计之基于springboot的购物平台设计与实现

计算机毕业设计之基于springboot的购物平台设计与实现

2026/7/28 0:06:55

由于移动应用技术的持续性的快速发展,现实生活中人们大多数都是通过移动手机、电脑等智能设备来完成生活中的事务。因此,许多的人工传统行业也开始与互联网结合,不再一味的依靠人工手动,努力打造半自动数字化甚至是全自动数字化模…

豆包AI绘图提示词失效真相:NLP模型层token截断机制首次披露,3招绕过字数限制

豆包AI绘图提示词失效真相:NLP模型层token截断机制首次披露,3招绕过字数限制

2026/7/28 0:06:55

更多请点击: https://codechina.net 第一章:豆包AI绘图提示词失效现象全景扫描 近期大量用户反馈,豆包(Doubao)AI绘图功能对常规提示词(Prompt)响应异常:语义明确的指令被忽略、中英…