首页 > 解决方案 > 猜测 XOR 密钥知道其中的一部分

问题描述

我试图猜测使用 Python 3 解密消息的密钥。我知道消息将类似于:crypto{1XXXXXX}其中 XXXXXXX 是消息的未知部分。加密消息是:'0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104'我有以下代码:

from pwn import xor

flkey=bytes.fromhex('0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104')

print(flkey)

y = xor(flkey, "crypto{1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}")

print(y)

xor(flkey, y)

我的问题是,我怎样才能找到只知道其中一部分的消息的其余部分?我对这个与 XOR 相关的主题很陌生。

编辑:当我打印(y)时,我得到:

b'crypto{1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}'

所以我猜括号之间的长度是34。

标签: pythonencryptionxorsecret-key

解决方案


密码学中 XOR 操作的弱点是A XOR B XOR A = B. 所以当你知道M对应的加密消息的明文部分时C,你立即得到那部分的密钥作为K = M XOR C

尤其:

 >>> cypher = bytes.fromhex('0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150104')
 >>> plaintext = b'crypto{1'
 >>> key = ''.join(chr(c ^ m) for c, m in zip(cypher, plaintext))
 >>> key
 'myXORkey'

这是整个关键的可能性很高(实际上是,这留作练习)。此字符串将根据需要重复多次以匹配纯文本长度。

现在假设,这不是全部关键。但是,我们知道密钥在循环中重复,因此我们已经知道的部分myXORkey,将在以后的某个地方重用。我们可以开始将它应用到密码中的各个地方,看看它什么时候开始有意义。这样我们就知道密钥长度和消息的部分。从这里有几种方法,最简单的是,因为我们知道明文的某些部分,我们可以通过感觉找到丢失的部分,然后从那里找到密钥的剩余部分。

以下属性可能会有所帮助:

  • 钥匙足够短
  • 关键是有道理的
  • 你知道纯文本所用的语言

If the key is as long as the message, is truly random, and used only once, the cypher cannot be broken (See One-time pad).

In a generic case when the plaintext or/and the key length is unknown, there is more sophisticated method based on the Hamming distance and transposition (The method was first discovered in 19th century by Friedrich Kasiski to analyze the Vigenère cipher.


推荐阅读