我尝试使用python重新实现Applied Cryptography
Protocols, Algorithms, and Source Code in C A book by Bruce Schneier
书中的简单Xor密码。可以在本书的第1.4节中找到该代码。
/* 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!='\0') {
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);
}
}
}
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时,它们不会返回相同的密文。
但是它们都很好地解密了各自的密文。 (表示相同的纯文本)
我的问题是:在给定相同的密钥和明文的情况下,为什么它们不生成相同的密文?
C版本对密钥进行单独的bytes异或。 Python版本使用的encode()
和decode()
适用于characters,而不是bytes。尝试使用带重音符号的字符或表情符号而不是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 )