密码学代码混乱

时间:2017-03-18 17:10:09

标签: python cryptography

我在python中编写了一次性密码的代码,但我遇到了一个问题。

我从ascii表中随机选择一个键(意思是它不必是一个字母) 在我用明文消息(只是字母表字母)之后,我得到了一个无意义的密文。 xor很好,我得到答案应该是荒谬的ascii字符,但我的问题是 - 我可以让代码返回一个字母吗?

我试图解决这个问题,到目前为止我的伪代码是:

for i in msglen:
  c[i]=msg[i] ^ key[i]
  if c[i]<65:
     c=(c+65)%26 #add 65 to bring up to alphabet, mod 26 in case it goes over
     c+=65       #add another 65 to make up for the modular reduction.

但显然我陷入了解密部分。

3 个答案:

答案 0 :(得分:3)

代码的第二部分是不必要的,会破坏您的计算。

一次性密码很简单,因为它需要相同的代码进行加密和解密,而且代码是一行 -

result = ''.join(chr(ord(s) ^ ord(k)) for s, k in zip(message, key))

使用字节数组会使其更简单

result = [s ^ k for s, k in zip(message, key)]

x ^ x = 0x ^ 0 = x以来,我们可以解析s ^ k ^ k = s,因此运行此行将同时使用密钥加密明文并使用该密钥解密加密文本(请注意,天气加密或解密取决于你的观点 - 计算机无法识别hj67si#s$jv38sok?g6e73可能不是明文。

答案 1 :(得分:0)

您不能只将XOR(ASCII编码)字符放在一起,因为它们通常不会产生有效字符 - 即使在正确实施时也是如此。

有两种主要方法可以解决这个问题。可以将字符的二进制编码进行异或,然后将其编码为十六进制或基数64.这当然会扩展您的密文与明文相比。要反向,首先解码,再次执行XOR,你将获得二进制编码的明文。

另一种方法是将可打印字符 - 您选择使用的字母 - 编码到范围[0,m],然后使用模块化添加而不是使用键{{1}进行XOR执行一次性打击垫。然后,您可以转换回可打印字符以获得密文。要反过来,你做同样的事情,但你减去(或添加否定键值:k)。

一个问题是,要继续使用一次性密钥,密钥流中的密钥值也必须在此范围内,如果您没有可用于生成范围内密钥的例程,这可能会非常棘手[0,m]给出一些随机位串。如果您想从随机位生成器(RBG)生成无偏数,请参阅我的答案here

答案 2 :(得分:0)

你所拥有的几乎肯定不是一次性垫。对于真正的OTP,密钥必须

  • 随机选择。
  • 只要明文。
  • 只使用一次。

如果您的密钥(我怀疑您在某处使用某种RNG)比您的明文短,那么您所拥有的密钥就是流密码,而不是OTP。

Stream Ciphers非常值得尊敬,但认为Stream Cipher是OTP是一个常见的业余错误。请查看RC4以获取简单但过时的Stream Cipher。