异或密码的实现问题

implementation problems with xor cipher

我尝试使用 python 重新实现书 Applied Cryptography Protocols, Algorithms, and Source Code in C A book by Bruce Schneier 中的简单 Xor 密码。代码可以在本书的 1.4 节中找到。

书中的 c 代码

/* Usage:  crypto key input_file output_file */ 
void main (int argc, char *argv[]) 
{ 
     FILE *fi, *fo; 
     char *cp; 
     int c; 
     if ((cp = argv[1]) && *cp!='[=10=]')  { 
         if ((fi = fopen(argv[2], "rb")) != NULL)  { 
             if ((fo = fopen(argv[3], "wb")) != NULL)  { 
                  while ((c = getc(fi)) != EOF)  { 
                       if (!*cp) cp = argv[1]; 
                       c ^= *(cp++); 
                       putc(c,fo); 
                  } 
                  fclose(fo); 
             } 
             fclose(fi); 
         } 
     } 
} 

我的 python 版本

import sys
def main(argc, argv):
    fi = open(argv[2], 'rb')
    fo = open(argv[3], 'wb')
    index = 0

    while True:
        x = fi.read(1)
        if not x: break
        x = ord(x.decode())
        fo.write( chr(x^ord( argv[1][index] )).encode() ) 
        index += 1 
        if index == len(argv): index = 0
    fi.close()
    fo.close()  


if __name__ == '__main__':
    # usage: python3.7 simple_xor.py <key> <inputfile> <outputfile>
    main( len(sys.argv), sys.argv ) 

它们都很好用。 BUT,给定相同的 plaintext(inputfile) 和相同的 key 以上两个代码,他们不treturn相同密文

然而他们都很好地解密了各自的密文。 (意思变成同一个明文)

我的问题是:为什么他们不生成相同的密文,给定相同的密钥和明文?

C 版本与密钥 XOR 单个 bytes。 Python 版本使用 encode()decode(),适用于 个字符 ,而不是 个字节 。尝试使用重音字符或表情符号而不是 ASCII 字符来查看差异。

此外,将 index 包裹到 0 的条件是错误的;您没有将它与密钥的长度进行比较。

也就是说,这个问题更多的是关于如何使用 Python 而不是密码学。

我做了非常小的改动 运行 它针对 C 版本,这似乎如您所愿:

我为 argv[1] 添加了一个键值分配,并将 #ord(x.decode()) 更改为 int(x.hex(),16).

我从 c​​ 代码中解密了密文,密文似乎与 python 生成的密文相同,输出是正确的。我用过:

cat cypher.txt
Cypher

./a.out key cypher.txt cypher.out
./crypt.py key cypher.out cypher.txt.test

密文相同:

$ ./a.out key cypher.txt cypher.out
$cat cypher.out 
(   
        a

$ ./crypt.py key cypher.txt cypher2.out
$ cat cypher2.out 
(   
        a

更新后的 python 代码:

#!/usr/local/opt/python3
import sys
def main(argc, argv):
    key=argv[1]
    fi = open(argv[2], 'rb')
    fo = open(argv[3], 'wb')
    index = 0

    while True:
        x = fi.read(1)
        if not x: break
        x = ord(x.decode()) #int(x.hex(),16) 
        fo.write( chr(x^ord( key[index] )).encode() ) 
        index += 1 
        if index == len(key): index = 0
    fi.close()
    fo.close()  


if __name__ == '__main__':
    # usage: python3.7 simple_xor.py <key> <inputfile> <outputfile>
    main( len(sys.argv), sys.argv )