所以下面有许多英文句子,使用相同的一次性密钥加密。我试图使用xor cipher解密它,所以我已经开始使用以下内容。
Guessing the first character as an "A"
7B (hex) XOR 41(hex of A) = 3A (hex)
3A XOR with 7B, 77, 6A, 6E, 6D, 7D
I get A , M, P , T , W , G
我想知道是否有更快的方法来做到这一点,因为猜测第一个角色并进行大量的反复试验似乎非常费时。试图为它编写一个python代码,但不知道如何开始。我希望这个问题有道理。
7B53D5EE7646755E999A2AFFDFCB353FA05077003BEB3FCCCB96 7B44DBF7760366108ADB2CB0D6D9323FA34C660C77FD22C7CB96 7757C2F925047B5189C97EF7CBD9337BE64D60093BF525CECA96 6A42DBEE6015344798C83BB0CDD0286FB65A614D6FF332C3D696 6E53D0EE60157051849A33FFCCD62871A11F6C1E3BFA3FCCCA96 6D5ED1F925076655DDD431E49ECB297EB44F250875F323C5C796 7D5FD7F46C097A518FC37EF1CACC207CAD1F76197AEE22C7CB96
答案 0 :(得分:0)
如果您直接Xor两个字符(十六进制),则不需要进行所有操作。
for i in range(len(allplain)):
k = chr (key[i])
p = chr (allplain[i])
c = chr ((ord(p)) ^ (ord(k)))
f2.write(c)
这是Python中One-Time Pad加密的完整实现。 我希望它能帮助那些在python中搜索解决方案的人,并且可以轻松地将其转换为Java。
答案 1 :(得分:0)
为了解码消息,计算机需要知道它是否正确猜到了密钥。我们知道这些消息是英文的,所以我们必须让计算机以某种方式理解。
为此,您可以使用统计模型告诉计算机字节序列是英语的可能性。也许最基本的统计模型是一个简单的字母频率表。 (这对您的特定密文很有效。)
将英语编码为字节的方式也很重要。我们可以猜测文本使用ASCII。因此,我们想要一个告诉我们每个字节值在以ASCII编码的英文文本中出现的可能性。
您可以在线查找此类表格,但通常此类信息的来源来自分析大量数据(" corpus")。数据匹配得越好(在样式,单词选择,拼写,大小写,间距的使用等方面 - 尽管只有在模型中检测到的东西才有意义)你试图解码的文本越好计算机解码往往会做。
有了模型,我们可以使用贝叶斯估计来确定最可能的密钥。这里的数学可能听起来有点可怕,但对于字母频率的情况,它变得非常简单。形式上,我们在所有可能的键上假设一个统一的先验,并假设明文是从模型给出的分布中独立选择的。然后,密钥的可能性与其所需的一组明文的(先验)可能性成比例,这可以从模型容易地计算出来。对于字母频率,这更容易,因为每个字母都是独立的,我们可以分别猜测密钥的每个字节。
(如果您使用的模型不能将文本分成小的独立块,您可能无法考虑每个键,因为会有太多,但您可以使用更智能的搜索算法,例如Dijkstra或A *,以避免通过避免不可能的前缀来考虑每个密钥。)
对于这个例子,我使用了来自The Blog Authorship Corpus的前100个文件(相当任意选择)。 (请注意,这个语料库是XML,所以我从技术上来说并没有正确解析它,但是元数据和语法开销的数量足够小,我认为这对于这个简单的例子并不重要。)
(免责声明:我不会写很多Python。)
import os
import glob
# Build language model by digesting corpus
frequency = [0 for i in xrange(0, 256)]
filecount = 0
for filename in glob.iglob(os.path.join('Corpus', '*')):
filecount += 1
if filecount > 100: break
with open(filename, 'rb') as f:
for c in f.read():
frequency[ord(c)] += 1
sum = 0
for count in frequency: sum += count
frequency = [(1.0 * count) / sum for count in frequency]
# Hard-coded message data
messages = [
b"\x7B\x53\xD5\xEE\x76\x46\x75\x5E\x99\x9A\x2A\xFF\xDF\xCB\x35\x3F\xA0\x50\x77\x00\x3B\xEB\x3F\xCC\xCB\x96",
b"\x7B\x44\xDB\xF7\x76\x03\x66\x10\x8A\xDB\x2C\xB0\xD6\xD9\x32\x3F\xA3\x4C\x66\x0C\x77\xFD\x22\xC7\xCB\x96",
b"\x77\x57\xC2\xF9\x25\x04\x7B\x51\x89\xC9\x7E\xF7\xCB\xD9\x33\x7B\xE6\x4D\x60\x09\x3B\xF5\x25\xCE\xCA\x96",
b"\x6A\x42\xDB\xEE\x60\x15\x34\x47\x98\xC8\x3B\xB0\xCD\xD0\x28\x6F\xB6\x5A\x61\x4D\x6F\xF3\x32\xC3\xD6\x96",
b"\x6E\x53\xD0\xEE\x60\x15\x70\x51\x84\x9A\x33\xFF\xCC\xD6\x28\x71\xA1\x1F\x6C\x1E\x3B\xFA\x3F\xCC\xCA\x96",
b"\x6D\x5E\xD1\xF9\x25\x07\x66\x55\xDD\xD4\x31\xE4\x9E\xCB\x29\x7E\xB4\x4F\x25\x08\x75\xF3\x23\xC5\xC7\x96",
b"\x7D\x5F\xD7\xF4\x6C\x09\x7A\x51\x8F\xC3\x7E\xF1\xCA\xCC\x20\x7C\xAD\x1F\x76\x19\x7A\xEE\x22\xC7\xCB\x96",
]
length = len(max(messages, key=lambda message: len(message)))
# Guess the key
key = []
for i in xrange(0, length):
best_keybyte = 0
best_keybyte_p = 0.0
for keybyte in xrange(0, 256):
# Calculate the prior probability of the plaintext for this key byte
p = 1.0
for message in messages:
if i < len(message):
messagebyte = ord(message[i])
plaintext = chr(messagebyte ^ keybyte)
p *= frequency[ord(plaintext)]
if p > best_keybyte_p:
best_keybyte = keybyte
best_keybyte_p = p
key.append(best_keybyte)
# Decode the messages based on the guess
for message in messages:
plaintext = ""
for i in xrange(0, len(message)):
plaintext += chr(ord(message[i]) ^ key[i])
print(plaintext)
这给出了:
eears and toast form wtni
erokser war has escalaiei
iave boats guard red inlh
ttores were shipped toyat
pedresday morning is ftnh
shee are not sharp enohge
cichionary attack stariei
(请注意,每一行都有一个尾随空格。)
显然这并不完美,但它足够接近你可以(使用你的英语知识)很容易手工修复错误。
使用优秀的英语模型可以帮助计算机自动修复此类问题。例如,字母频率模型不知道消息可能以大写字母开头。一个共同的改进是考虑字母对的频率。
答案 2 :(得分:-1)
你能告诉我一些关于它的事吗?听起来我只想尝试对加密消息中的每个字符使用相同的密钥位,这只有在消息使用相同的密钥位对所有字符进行加密时才有效。在这种情况下,您可以对十六进制字符进行频率分析,看看哪些最常出现,并以这种方式计算出来?