AES-encryptor实战:从CTF题目到Python加解密工具开发
1. AES加密基础:从CTF题目入门
1.1 什么是AES加密?
AES(Advanced Encryption Standard)是一种对称加密算法,广泛应用于数据保护领域。它使用固定长度的密钥(128/192/256位)对数据进行加密和解密,具有安全性高、效率好的特点。在CTF比赛中,AES题目常出现在Crypto类别,考察选手对加密模式(如ECB、CBC)和填充方式的理解。
1.2 典型CTF题目分析
让我们从一个实际的CTF题目代码片段开始:
from Crypto.Cipher import AES import base64 def aes_encrypt(data): key = b'ThisIsASecretKey' # 16字节密钥 cipher = AES.new(key, AES.MODE_ECB) padded_data = data + b'\0' * (16 - len(data) % 16) # 零填充 return cipher.encrypt(padded_data) encrypted = aes_encrypt(b'flag{test_flag}') print(base64.b64encode(encrypted).decode())这段代码展示了AES-ECB模式的基本使用方式。ECB模式的主要问题是相同的明文块会加密成相同的密文块,这会导致安全性问题。
2. AES-ECB模式的漏洞与攻击
2.1 ECB模式的工作原理
ECB(Electronic Codebook)是最简单的AES加密模式,它将明文分成固定大小的块,每个块独立加密。这种模式的主要特点是:
- 不需要初始化向量(IV)
- 并行加密效率高
- 相同明文块产生相同密文块
2.2 实际漏洞案例分析
观察题目中的加密函数:
def aes(txt): data = txt.encode("utf-8") key = random.randint(100000, 999999) key = str(key) + str(key) + str(key)[0:4] data = data + b"It is real flag!" cipher = AES.new(key, AES.MODE_ECB) return cipher.encrypt(data)这里有几个关键点:
- 密钥生成方式不安全(使用随机数但范围有限)
- 使用ECB模式
- 明文末尾添加了固定字符串
2.3 破解思路与实现
我们可以通过暴力破解密钥的方式解密flag:
from Crypto.Cipher import AES import base64 encrypted_flag = b'iVBORw0KGgo...' # 实际base64编码的密文 for i in range(100000, 999999): key = str(i) * 2 + str(i)[0:4] cipher = AES.new(key.encode(), AES.MODE_ECB) try: decrypted = cipher.decrypt(encrypted_flag) if b"It is real flag!" in decrypted: print(f"Found key: {key}") print(decrypted.decode()) break except: continue这种方法利用了密钥空间有限(100000-999999)和已知明文后缀的特点。
3. 构建Python加解密工具
3.1 工具功能设计
基于上述分析,我们可以开发一个多功能AES工具,包含以下功能:
- 支持ECB/CBC等不同模式
- 自动处理PKCS7填充
- 提供加密/解密功能
- 支持文件加解密
- 包含密钥爆破功能
3.2 核心代码实现
from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad import base64 import argparse class AESHelper: def __init__(self, key, mode=AES.MODE_ECB, iv=None): self.key = key self.mode = mode self.iv = iv if iv else b'\0'*16 # 默认零向量 def encrypt(self, data): cipher = AES.new(self.key, self.mode, iv=self.iv) return cipher.encrypt(pad(data, AES.block_size)) def decrypt(self, data): cipher = AES.new(self.key, self.mode, iv=self.iv) return unpad(cipher.decrypt(data), AES.block_size) def brute_force_ecb(encrypted, known_suffix, key_range): for i in key_range: key = (str(i)*2 + str(i)[0:4]).encode() helper = AESHelper(key) try: decrypted = helper.decrypt(encrypted) if known_suffix in decrypted: return key, decrypted except: continue return None, None4. 高级功能与安全实践
4.1 支持多种加密模式
除了ECB模式,我们还可以实现更安全的CBC模式:
def encrypt_cbc(self, data): cipher = AES.new(self.key, AES.MODE_CBC, iv=self.iv) return cipher.encrypt(pad(data, AES.block_size)) def decrypt_cbc(self, data): cipher = AES.new(self.key, AES.MODE_CBC, iv=self.iv) return unpad(cipher.decrypt(data), AES.block_size)4.2 文件加解密实现
def encrypt_file(input_file, output_file, key, mode): helper = AESHelper(key, mode) with open(input_file, 'rb') as f: data = f.read() encrypted = helper.encrypt(data) with open(output_file, 'wb') as f: f.write(encrypted) def decrypt_file(input_file, output_file, key, mode): helper = AESHelper(key, mode) with open(input_file, 'rb') as f: data = f.read() decrypted = helper.decrypt(data) with open(output_file, 'wb') as f: f.write(decrypted)4.3 安全使用建议
- 避免使用ECB模式处理敏感数据
- 使用强随机密钥(至少128位)
- 对于CBC模式,确保每次加密使用不同的IV
- 正确处理填充(推荐PKCS7)
- 考虑使用认证加密模式如GCM
5. 实战:从题目到工具开发
5.1 完整解题流程
- 分析题目加密函数特点
- 识别ECB模式和密钥生成方式
- 编写爆破脚本尝试所有可能的密钥
- 验证解密结果中的已知明文
- 提取flag并验证
5.2 工具封装与使用
我们可以将上述功能封装成命令行工具:
if __name__ == "__main__": parser = argparse.ArgumentParser(description='AES加解密工具') parser.add_argument('-m', '--mode', choices=['ecb', 'cbc'], default='ecb') parser.add_argument('-k', '--key', help='加密密钥') parser.add_argument('-i', '--iv', help='初始化向量(CBC模式需要)') parser.add_argument('-e', '--encrypt', action='store_true', help='加密模式') parser.add_argument('-d', '--decrypt', action='store_true', help='解密模式') parser.add_argument('-f', '--file', help='文件路径') parser.add_argument('-b', '--brute', help='暴力破解模式(仅ECB)') args = parser.parse_args() if args.brute: # 暴力破解逻辑 pass else: # 正常加解密逻辑 pass6. 常见问题与调试技巧
6.1 常见错误处理
- 填充错误:确保加密解密使用相同的填充方式
- 密钥长度错误:AES密钥必须是16/24/32字节
- IV不匹配:CBC模式需要相同的IV才能正确解密
6.2 性能优化建议
- 对于暴力破解,使用多线程加速
- 预先计算可能的密钥减少重复计算
- 使用C扩展(如PyCryptodome)提高加密速度
我在实际开发中发现,正确处理填充是AES加解密中最容易出错的部分。特别是在解密时,如果填充验证失败会抛出异常,这需要仔细检查加密解密流程是否一致。另一个常见误区是忽视加密模式的选择,ECB模式虽然简单但不安全,在真实场景中应优先考虑CBC或GCM模式。
