跳到主要内容

重复密钥 XOR 与已知明文攻击

XOR 本身不是加密方案。只要同一段密钥重复使用,并且攻击者能拿到一组明文和对应密文,就可以直接恢复密钥,再解密其他消息。靶场里它常以“自研安全消息系统”“测试加密数据”的形式出现。

识别特征

常见信号:

  • 页面展示长十六进制字符串。
  • 测试站泄露 testdata.txtsample.txtmessage.txt
  • 文档或注释里直接提到 XORkeyencrypt
  • 同一系统里既有“历史密文”,又有“测试明文”。

基本原理

XOR 满足:

ciphertext = plaintext XOR key
key = ciphertext XOR plaintext
plaintext = ciphertext XOR key

如果密钥循环使用,恢复出来的 key 会呈现重复周期。

恢复最短循环密钥

python3 - <<'PY'
from binascii import unhexlify

ct = unhexlify("HEX_CIPHERTEXT_HERE")
pt = open("/tmp/plain.txt", "rb").read().rstrip(b"\n")

stream = bytes(c ^ p for c, p in zip(ct, pt))

for size in range(1, len(stream) + 1):
candidate = stream[:size]
if stream == (candidate * (len(stream) // size + 1))[:len(stream)]:
print(candidate.decode(errors="replace"))
break
PY

解密其他密文

python3 - <<'PY'
from binascii import unhexlify

key = b"recovered-key"
ct = unhexlify("HEX_CIPHERTEXT_HERE")
pt = bytes(c ^ key[i % len(key)] for i, c in enumerate(ct))
print(pt.decode(errors="replace"))
PY

结果判断

有效结果通常会出现:

  • 可读英文句子。
  • 用户名、密码、后台路径。
  • 和页面主题一致的短语。
  • 多段密文用同一个 key 能解出相似格式。

防坑点

  • 明文和密文长度不一致时,只能恢复重叠部分。
  • Hex 字符串必须先 unhexlify,不要直接对 ASCII 字符做 XOR。
  • 文本末尾换行会影响最后一个字节,必要时用 rstrip(b"\n")
  • 如果恢复出的 key 没有短周期,可能不是重复密钥 XOR,或者明文不对应这段密文。

防御建议

  • 不使用自研加密。
  • 同一密钥流绝不能重复使用。
  • 使用经过审计的 AEAD 模式,例如 AES-GCM、ChaCha20-Poly1305。
  • 测试明文和密钥材料不能放在可访问 Web 路径。

来源案例

  • The Planets: Earth:测试站泄露 testdata.txt,结合主站历史密文恢复重复密钥 earthclimatechangebad4humans,进而登录后台。