最后编辑:我已经弄清楚问题是什么(请参阅下面我自己的答案),但我似乎无法将问题标记为已回答。如果有人可以回答我在下面的回答中提出的问题,即这是 Cython 中的错误还是这是 Cython 的预期行为,我将标记that答案被接受,因为这将是从中获得的最有用的教训,恕我直言。
首先,我必须首先说,我三天来一直在试图解决这个问题,但我只是在用头撞墙。据我从文档中可以看出,我做的事情是正确的。显然,我不能正确地做事,因为如果我是,我就不会有问题(对吧?)。
无论如何,我正在研究 mcrypt 到 Python 的绑定。它应该适用于 Python 2 和 Python 3(尽管它尚未针对 Python 2 进行测试)。可用在我的网站上 http://mike.trausch.us/software/mcrypt-0.0.0.tar.gz,链接是因为它太大而无法包含在帖子中,并且考虑到我不知道what我做错了,我什至无法隔离可能有问题的代码。显示问题的脚本是也在我的网站上 http://mike.trausch.us/software/test.py。该脚本只提供 100 个除了字母“a”之外什么都没有的块(无论加密算法/加密模式使用什么块大小),当然应该得到一个“a”块作为往返的结果。但事实并非如此(总是)。这是单次运行的输出:
Wed Dec 15 10:35:44 EST 2010
test.py:5: McryptSecurityWarning: get_key() is not recommended
return ''.join(['{:02x}'.format(x) for x in o.get_key()])
key: b'\x01ez\xd5\xa9\xf9\x1f)\xa0G\xd2\xf2Z\xfc{\x7fn\x02?,\x08\x1c\xc8\x03\x061X\xb5\xc9\x99\xd0\xca'
key: b'\x01ez\xd5\xa9\xf9\x1f)\xa0G\xd2\xf2Z\xfc{\x7fn\x02?,\x08\x1c\xc8\x03\x061X\xb5\xc9\x99\xd0\xca'
16
self test result: 0
enc parameters: {'salt': '6162636465666768', 'mode': 'cbc', 'algorithm': 'rijndael-128', 'iv': '61626364616263646162636461626364'}
dec parameters: {'salt': '6162636465666768', 'mode': 'cbc', 'algorithm': 'rijndael-128', 'iv': '61626364616263646162636461626364'}
enc key: 01657ad5a9f91f29a047d2f25afc7b7f6e023f2c081cc803063158b5c999d0ca
dec key: 01657ad5a9f91f29a047d2f25afc7b7f6e023f2c081cc803063158b5c999d0ca
Stats: 88 / 100 good packets (88.0%)
#5: b'aaaaaaaaaaaaaaaa' != b'\xa6\xb8\xf9\td\x8db\xf6\x00Y"ST\xc6\x9b\xe7'
#6: b'aaaaaaaaaaaaaaaa' != b'aaaaaaa1\xb3@\x8d\xff\xf9\xafpy'
#13: b'aaaaaaaaaaaaaaaa' != b'\xb9\xc8\xaf\x1f\xb8\x8c\x0b_\x15s\x9d\xecN,*w'
#14: b'aaaaaaaaaaaaaaaa' != b'aaaaaaaaaaaaa\xeb?\x13'
#49: b'aaaaaaaaaaaaaaaa' != b'_C\xf2\x15\xd5k\xe1XKIF5k\x82\xa4\xec'
#50: b'aaaaaaaaaaaaaaaa' != b'aaaaaaaaaaa+\xdf>\x01\xee'
#74: b'aaaaaaaaaaaaaaaa' != b'\x1c\xdf0\x05\xc7\x0b\xe9\x93H\xc5B\xd7\xcfj+\x03'
#75: b'aaaaaaaaaaaaaaaa' != b'aaaaaaaaaaaaw+\xed\x0f'
#79: b'aaaaaaaaaaaaaaaa' != b"\xf2\x89\x1ct\xe1\xeeBWo\xb4-\xb9\x085'\xef"
#80: b'aaaaaaaaaaaaaaaa' != b'aaaaaaaaaaa\xcc\x01n\xf0<'
#91: b'aaaaaaaaaaaaaaaa' != b'g\x02\x08\xbf\xa5\xd7\x90\xc1\x84D\xf3\x9d$a)\x06'
#92: b'aaaaaaaaaaaaaaaa' != b'aaaaaaaaaaaaaaa\x01'
奇怪的是它是exactly对于给定的(算法,模式)对也是如此。我可以更改算法,这将导致不同的往返,但当我不更改算法时,每次运行总是相同的。我完全被难住了。另外,正如您在上面的输出中看到的那样,总是有两个连续的块被损坏:块 5 和 6、13 和 14 等。所以,有一个模式,但无论出于何种原因,我无法弄清楚该模式准确指向什么。
我意识到我可能在这里问了很多问题:我无法隔离一小段代码,并且可能需要熟悉 mcrypt 和 Python。唉,经过三天的思考,我需要暂时远离这个问题,所以我把这个贴在这里,希望也许当我暂时摆脱这个问题时,(a)某人将看到我在哪里引入了错误,(b)当我稍后回到问题时,我将能够看到我的错误,或者(c)某人或我自己可以找到问题,这可能不是我的代码中的错误,但是绑定过程或库本身的错误。
我没有做的一件事是尝试使用 mcrypt 库的另一个版本。我正在使用 Cython 0.13、Python 3.1 和 mcrypt 2.5.8 进行工作,所有这些都是由 Ubuntu 在 Ubuntu 10.10 中分发的(除了 Cython,它是我从 PyPi 获得的)。但是我使用 PHP 应用程序管理系统,这些应用程序运行良好,并且在 Ubuntu 10.10 上使用 mcrypt 没有数据损坏,所以我没有理由相信它是 mcrypt 的构建,所以这只留下了......好吧,我在某个地方出了问题, 我认为。
无论如何,我非常感谢任何能够提供帮助的人。我开始觉得自己快要疯了,因为我已经连续几天不间断地研究这个问题,而且我感觉解决方案可能就在我面前,但我看不到它。
Edit:有人指出我应该使用 memcpy 而不是 strncpy。我这样做了,但现在测试脚本显示every块不正确。让我比以前更加困惑......这是新的输出在pastebin上 http://pastebin.com/sA0RtZK7.
Edit 2:我回到计算机并再次查看它,我只是在各处添加打印语句以查找可能出现问题的地方。 raw_encrypt.step(input) 函数中的以下代码:
cdef char* buffer = <char*>malloc(in_len)
print in_bin[:in_len]
memcpy(buffer, <const_void *>in_bin, in_len)
print "Before/after encryption"
print buffer[:in_len]
success = cmc.mcrypt_generic(self._mcStream, <void*>buffer, in_len)
print buffer[:in_len]
第一个打印语句显示了预期的内容,即传入的明文。但是,第二个打印语句显示了完全不同的内容,它应该是相同的。看来 Cython 发生了一些我不完全理解的事情。