Повреждение данных: где ошибка? - PullRequest
7 голосов
/ 15 декабря 2010

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

<Ч />

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

В любом случае, я работаю над привязкой mcrypt к Python. Он должен работать как с Python 2, так и с Python 3 (хотя он не проверен для Python 2). Он доступен на моем сайте , на него есть ссылки, потому что он слишком велик для размещения в посте, и, учитывая, что я не знаю что я делаю неправильно, я даже не могу выделить то, что может быть код проблемы. Сценарий, который показывает проблему также на моем сайте . Сценарий просто передает 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'

Странная часть в том, что точно одинаков для данной пары (алгоритм, режим). Я могу изменить алгоритм, и это приведет к различным циклам, но всегда одинаково для каждого запуска, когда я не изменяю алгоритм. Я абсолютно в тупике. Кроме того, это всегда два блока подряд, которые повреждены, как вы можете видеть в выходных данных выше: блоки 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. Я сделал это, но теперь тестовый скрипт показывает, что каждый блок неверен. Цвет меня еще больше смутил, чем раньше ... вот новый вывод на pastebin .

Редактировать 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]

Первый оператор print показывает ожидаемую вещь, открытый текст, который передается. Однако второй оператор показывает что-то совершенно другое, которое должно быть идентичным.Похоже, что с Cython происходит что-то, что я не до конца понимаю.

Ответы [ 2 ]

2 голосов
/ 15 декабря 2010

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

Проблема связана со строкой memcpy. Я привел второй параметр к , который соответствует определению Cython в файле pxd, но, очевидно, это заставляет Cython компилировать код иначе, чем при использовании , последний заставляет 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)

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

0 голосов
/ 15 декабря 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...