别光看WP!手把手教你用Python复现蓝桥杯网络安全赛的“数字水印”和“RC4解密”题
·
从零复现CTF赛题:Python实现数字水印提取与RC4解密实战
在网络安全竞赛中,数字水印和RC4算法是常见的考察点。本文将带您用Python完整复现这两个技术点的解题过程,通过可运行的代码演示如何从图片中提取隐藏信息以及解密RC4加密数据。
1. 环境准备与工具安装
1.1 安装必要Python库
首先需要安装以下Python库,这些库将帮助我们处理图像和实现加密算法:
pip install opencv-python pywt numpy
注意:建议使用Python 3.8或更高版本,某些库在不同版本中可能有兼容性问题
1.2 准备测试文件
我们需要准备两个测试文件:
- 包含水印的图片文件(如
watermarked.png) - 加密后的数据文件(如
encrypted.bin)
这些文件可以从CTF比赛提供的素材中获取,或者自行创建测试用例。
2. 数字水印提取实战
数字水印技术常用于版权保护和信息隐藏,我们将使用离散小波变换(DWT)方法提取隐藏信息。
2.1 DWT数字水印原理
离散小波变换将图像分解为不同频率的子带:
- LL:低频近似分量
- LH、HL、HH:高频细节分量
水印信息通常嵌入在高频分量中,因为人类视觉对高频变化不敏感。
2.2 Python实现水印提取
以下是完整的数字水印提取类实现:
import cv2
import numpy as np
import pywt
class WatermarkExtractor:
def __init__(self, watermarked_img_path, key=20, weights=[0.2, 0.2, 0.5, 0.4]):
self.key = key
self.img = cv2.imread(watermarked_img_path, cv2.IMREAD_GRAYSCALE)
self.coef = weights
def inverse_arnold(self, img):
"""逆向Arnold变换,用于还原水印图像"""
r, c = img.shape
p = np.zeros((r, c), np.uint8)
a, b = 1, 1
for _ in range(self.key):
for i in range(r):
for j in range(c):
x = ((a*b + 1)*i - b*j) % r
y = (-a*i + j) % c
p[x, y] = img[i, j]
return p
def extract(self, output_path='extracted_watermark.png'):
"""提取水印并保存结果"""
# 三级小波分解
coeffs = pywt.wavedec2(self.img, 'db2', level=3)
cA3, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1) = coeffs
# 水印提取算法
extracted_watermark = pywt.waverec2([
cA3 * self.coef[0],
(cH3 * self.coef[1], cV3 * self.coef[2], cD3 * self.coef[3])
], 'db2')
# 后处理
extracted_watermark = np.clip(extracted_watermark, 0, 255).astype(np.uint8)
extracted_watermark = self.inverse_arnold(extracted_watermark)
# 保存结果
cv2.imwrite(output_path, extracted_watermark)
return extracted_watermark
# 使用示例
if __name__ == "__main__":
extractor = WatermarkExtractor("watermarked.png")
watermark = extractor.extract()
print("水印提取完成,已保存为extracted_watermark.png")
提示:Arnold变换是一种图像置乱技术,常用于水印预处理,key参数需要与嵌入时一致才能正确还原
2.3 常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 提取的水印模糊 | 权重系数不匹配 | 调整weights参数 |
| 提取失败 | 小波基不匹配 | 尝试使用'db1'或'haar'小波 |
| 图像尺寸不符 | 原始图像尺寸变化 | 确保使用原始尺寸图像 |
3. RC4算法解密实战
RC4是一种流加密算法,在CTF中经常出现。我们将实现完整的RC4解密过程。
3.1 RC4算法原理
RC4包含两个主要阶段:
- 密钥调度算法(KSA):初始化状态数组
- 伪随机生成算法(PRGA):生成密钥流
3.2 Python实现RC4解密
class RC4:
def __init__(self, key):
self.key = key
self.S = list(range(256))
self.T = [ord(c) for c in key] * (256 // len(key)) + [ord(c) for c in key][:256 % len(key)]
self.initialize()
def initialize(self):
"""KSA密钥调度算法"""
j = 0
for i in range(256):
j = (j + self.S[i] + self.T[i]) % 256
self.S[i], self.S[j] = self.S[j], self.S[i]
def decrypt(self, ciphertext):
"""解密数据"""
plaintext = []
i = j = 0
for byte in ciphertext:
i = (i + 1) % 256
j = (j + self.S[i]) % 256
self.S[i], self.S[j] = self.S[j], self.S[i]
k = self.S[(self.S[i] + self.S[j]) % 256]
plaintext.append(byte ^ k)
return bytes(plaintext)
# 使用示例
if __name__ == "__main__":
# 示例:解密蓝桥杯CTF题目
encrypted_data = bytes.fromhex("已知的加密数据十六进制字符串")
key = "CTF竞赛提供的密钥"
rc4 = RC4(key)
decrypted = rc4.decrypt(encrypted_data)
print(f"解密结果: {decrypted.decode('utf-8', errors='ignore')}")
3.3 RC4解密技巧
在实际CTF比赛中,RC4解密可能遇到以下情况:
- 密钥未知 :尝试常见密钥或暴力破解
- 部分明文已知 :利用已知明文攻击恢复密钥
- 非标准实现 :检查是否有算法修改点
# 暴力破解示例(简单密钥)
def brute_force_rc4(ciphertext, known_plaintext_part, max_key_length=3):
from itertools import product
from string import printable
for length in range(1, max_key_length+1):
for possible_key in product(printable, repeat=length):
key = ''.join(possible_key)
rc4 = RC4(key)
decrypted = rc4.decrypt(ciphertext)
if known_plaintext_part in decrypted.decode('utf-8', errors='ignore'):
return key, decrypted
return None, None
4. 综合实战:CTF题目复现
让我们模拟一个完整的CTF解题流程,结合数字水印和RC4解密技术。
4.1 题目分析
假设题目提供:
- 一张包含flag提示的图片(使用DWT水印)
- 一个加密的flag文件(使用RC4加密)
4.2 解题步骤
- 从图片中提取水印,获取RC4密钥提示
- 使用获取的密钥解密加密文件
- 提取最终flag
# 完整解题代码
def solve_ctf_challenge():
# 第一步:提取水印获取密钥提示
img_extractor = WatermarkExtractor("challenge_image.png")
watermark = img_extractor.extract("extracted_hint.png")
print("水印提取完成,请查看extracted_hint.png获取密钥提示")
# 假设从水印中获取到密钥是"CTF2023"
key = "CTF2023"
# 第二步:解密加密文件
with open("encrypted_flag.bin", "rb") as f:
encrypted_data = f.read()
rc4 = RC4(key)
flag = rc4.decrypt(encrypted_data)
print(f"解密得到的flag: {flag.decode('utf-8')}")
# 执行解题
solve_ctf_challenge()
4.3 调试技巧
在复现过程中可能会遇到各种问题,以下是一些实用调试方法:
- 可视化中间结果 :对于图像处理步骤,保存中间图像便于分析
- 单元测试 :对RC4算法单独测试,确保加解密正确性
- 边界检查 :特别注意图像尺寸是否为2的幂次方(小波变换要求)
# 调试示例:检查小波分解结果
def debug_dwt():
import matplotlib.pyplot as plt
img = cv2.imread("test.png", cv2.IMREAD_GRAYSCALE)
coeffs = pywt.wavedec2(img, 'db2', level=3)
# 可视化各子带
plt.figure(figsize=(12, 8))
titles = ['Approximation', 'Horizontal', 'Vertical', 'Diagonal']
for i, (cH, cV, cD) in enumerate(coeffs[1:]):
plt.subplot(3, 3, i*3+1)
plt.imshow(cH, cmap='gray')
plt.title(f'Level {i+1} Horizontal')
plt.subplot(3, 3, i*3+2)
plt.imshow(cV, cmap='gray')
plt.title(f'Level {i+1} Vertical')
plt.subplot(3, 3, i*3+3)
plt.imshow(cD, cmap='gray')
plt.title(f'Level {i+1} Diagonal')
plt.tight_layout()
plt.show()
通过本文的实战演练,您应该已经掌握了使用Python复现CTF中数字水印和RC4解密题目的完整流程。在实际比赛中,关键在于理解题目背后的技术原理,并将其转化为可执行的代码解决方案。
更多推荐
所有评论(0)