Cryptopals Challenge 5
题目
Challenge 5 Set 1 - The Cryptopals Crypto Challenges
重复密钥 XOR 加密
给定字符串
1
2
Burning 'em, if you ain't quick and nimble
I go crazy when I hear a cymbal
使用密钥 ICE
进行重复密钥 XOR 加密,可以得到以下结果:
1
2
0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272
a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f
解析
知识点
- 重复密钥 XOR 加密其实是维吉尼亚密码的一种变体,他的密钥比信息要短,密钥逐字节加密后重复使用,以覆盖整个信息。
- 维吉尼亚密码:是一种多表密码。与传统的凯撒密码(Caesar Cipher)不同,在维吉尼亚密码中,密钥是一个单词或短语,加密过程中,密钥中的字符逐个应用到明文文本的字符上,然后根据密钥字符的位置来执行字母的位移操作。
分析
我们可以先把密钥的长度扩展到与明文长度一直,进而逐字节异或即可。
- 明文长度除以密钥长度,得到商和余数,便于扩展密钥长度
- 给定的明文和密钥都是字符串,我们要先通过
.encode()
编码成字节串。
解决方案
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
plaintext = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"
key = "ICE"
target_string = "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f"
def repeating_xor(text: bytes, key: bytes) -> bytes:
# 明文长度除以密钥长度,得到商和余数,便于扩展密钥长度
quotient, remainder = divmod(len(text), len(key))
key_extend = bytes(key * quotient + key[:remainder])
# 逐个字节异或
return bytes([x ^ y for x, y in zip(text, key_extend)])
# 先把字符串编码成字节串
byte_string = plaintext.encode()
byte_Key = key.encode()
ciphertext = repeating_xor(byte_string, byte_Key)
print(ciphertext.hex() == target_string)
运行结果
1
True
参考
本文由作者按照 CC BY 4.0 进行授权