Вопрос

Последнее редактирование: Я понял, в чем проблема (см. мой собственный ответ ниже), но, похоже, не могу пометить вопрос как отвеченный.Если кто-то сможет ответить на вопросы, которые у меня есть в моем ответе ниже, а именно, является ли это ошибкой в ​​Cython или это предполагаемое поведение Cython, я отмечу что ответьте как принято, потому что, ИМХО, это будет самый полезный урок, который можно извлечь из этого.


Во-первых, я должен начать с того, что пытаюсь разобраться в этом уже три дня и просто бьюсь головой о стену.Насколько я могу судить по документации, я все делаю правильно.Однако очевидно, что я не могу делать что-то правильно, потому что если бы я был прав, у меня не было бы проблем (верно?).

В любом случае я работаю над привязкой mcrypt к Python.Он должен работать как с Python 2, так и с Python 3 (хотя для Python 2 он не тестировался).Это доступно на моем сайте, ссылка связана, потому что она слишком велика, чтобы ее можно было включить в сообщение, и учитывая, что я не знаю что Я делаю неправильно, я даже не могу выделить, в чем может быть проблемный код.Сценарий, показывающий проблему: также на моем сайте.Сценарий просто передает 100 блоков, не содержащих ничего, кроме буквы «а» (независимо от размера блока, который использует алгоритм/режим шифрования), и, конечно же, должен получить блок «а» в результате обратного обхода.Но это не так (всегда).Вот результат одного запуска:

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'

Самое странное, что это точно то же самое для данной пары (алгоритм, режим).Я могу изменить алгоритм, и это приведет к разным обращениям туда и обратно, но всегда одинаковым для каждого запуска, если я не меняю алгоритм.Я совершенно в тупике.Кроме того, всегда два блока подряд повреждены, как вы можете видеть в выводе выше:блоки 5 и 6, 13 и 14 и т. д.Итак, закономерность существует, но я по какой-то причине не могу понять, на что именно она указывает.

Я понимаю, что, вероятно, прошу здесь многого:Я не могу выделить небольшой фрагмент кода, и, вероятно, потребуется знакомство как с mcrypt, так и с Python.Увы, после трех дней ломания над этим головы, мне нужно ненадолго отойти от проблемы, поэтому публикую это здесь в надежде, что, возможно, пока я отдохну от этой проблемы, либо (а) кто-то увижу, где я допустил ошибку, (б) я смогу увидеть свою ошибку, когда вернусь к проблеме позже, или (в) кто-то или я смогу найти проблему, которая, возможно, не является ошибкой в ​​моем коде, но ошибка в процессе привязки или самой библиотеки.

Единственное, чего я не сделал, — это не попытался использовать другую версию библиотеки mcrypt.Я работаю с Cython 0.13, Python 3.1 и mcrypt 2.5.8, которые распространяются Ubuntu в Ubuntu 10.10 (кроме Cython, который я получил от PyPi).Но я управляю системами с приложениями PHP, которые работают нормально и используют mcrypt в Ubuntu 10.10 без повреждения данных, поэтому у меня нет оснований полагать, что это сборка mcrypt, так что просто выходит… ну, где-то с моей стороны что-то не так , Я думаю.

В любом случае я благодарю всех, кто может помочь.Мне начинает казаться, что я схожу с ума, потому что я работал над этой проблемой почти без перерыва в течение нескольких дней, и у меня такое чувство, что решение, вероятно, находится прямо передо мной, но я не вижу его.

Редактировать:Кто-то заметил, что мне следует использовать memcpy вместо strncpy.Я сделал это, но теперь тестовый сценарий показывает, что каждый блок неправильный.Раскрась меня еще больше в замешательстве, чем раньше...вот новый результат на пастебине.

Редактировать 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 происходит что-то, чего я не совсем понимаю.

Это было полезно?

Решение

Ой, ненавижу это делать (отвечу на свой вопрос), но я нашел ответ:Это особенность Cython, которую мне придется изучить (я не знаю, намеренная ли это особенность или это ошибка).

Проблема связана со строкой memcpy.Я привожу второй параметр к <const_void*>, который соответствует определению Cython в файле pxd, но, по-видимому, это заставляет Cython компилировать код иначе, чем при использовании <char*>, последний вынуждает Cython вместо этого передавать указатель на фактические байты. (я думаю?) указателя на сам объект/переменную Python.

Итак, вместо этого:

cdef char* buffer = <char*>malloc(in_len)
memcpy(buffer, <const_void *>in_bin, in_len)
success = cmc.mcrypt_generic(self._mcStream, <void*>buffer, in_len)

Это должно быть следующее:

cdef char* buffer = <char*>malloc(in_len)
memcpy(buffer, <char *>in_bin, in_len)
success = cmc.mcrypt_generic(self._mcStream, <void*>buffer, in_len)

Какая странная причуда.Честно говоря, я бы ожидал, что любой приведение будет указывать на одно и то же место, но кажется, что приведение также может влиять на поведение.

Другие советы

Я сталкивался с подобными результатами, когда происходило что-то забавное из-за использования неправильного вектора инициализации (т.использование другого IV для шифрования, чем для дешифрования) и выбор режима шифрования.В качестве проверки здравомыслия попробуйте переключиться с CBC на ECB.

Другая возможность заключается в том, что одна из ваших переменных рандомизируется (с новым начальным значением, основанным на времени), хотя этого не должно быть.В этом случае вы можете привести к более частому повреждению данных, установив задержку между этапами шифрования и дешифрования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top