7

最後の編集:問題が何であるかを把握しました (以下の自分の回答を参照してください)が、質問を回答済みとしてマークすることはできません。以下の私の回答にある質問に誰かが答えることができる場合、つまり、これは Cython のバグですか、それとも Cython の意図した動作ですか? .


最初に、私はこれを理解しようと 3 日間試みてきたと言うことから始めなければなりません。私はただ頭を壁にぶつけています。ドキュメントからわかる限り、私は正しくやっています。明らかに、私は物事を正しく行うことはできません。

いずれにせよ、私は mcrypt を Python にバインドする作業を行っています。Python 2 と Python 3 の両方で動作するはずです (ただし、Python 2 ではテストされていません)。投稿に含めるには大きすぎるため、リンクされています。また、何が間違っているのかわからないため、問題のコードを特定することさえできません問題を示すスクリプトも私のサイトにあります。スクリプトは、文字「a」のみの 100 ブロックをフィードするだけで (暗号化アルゴリズム/暗号化モードが使用するブロック サイズに関係なく)、もちろん、ラウンドトリップの結果として「a」のブロックを取得する必要があります。しかし、そうではありません(常に)。これを 1 回実行した場合の出力は次のとおりです。

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 など、常に 2 つのブロックが連続して破損しています。したがって、パターンはありますが、何らかの理由で把握できません。そのパターンが正確に指しているもの。

私はおそらくここで多くの質問をしていることに気付きました.コードの小さな断片を分離することはできません.mcryptとPythonの両方に精通している必要があります. 悲しいかな、これに頭を悩ませてから 3 日後、私はこの問題から少し離れる必要があります。 (b) 後で問題に戻ったときに自分のバグを確認できる、または (c) 誰かまたは自分自身が自分のコードのバグではないかもしれない問題を見つけることができるバインディング プロセスまたはライブラリ自体のバグ。

私が行っていないことの 1 つは、別のバージョンの mcrypt ライブラリを使用しようとしたことです。Cython 0.13、Python 3.1、および mcrypt 2.5.8 を使用して作業を行っています。これらはすべて、Ubuntu 10.10 で Ubuntu によって配布されています (PyPi から取得した Cython を除く)。しかし、私は問題なく機能し、Ubuntu 10.10 でデータ破損なしに mcrypt を使用している PHP アプリケーションでシステムを管理しているので、それが mcrypt のビルドであると信じる理由はありません。 、 おもう。

いずれにせよ、助けてくれる人には心から感謝します。私はこの問題に何日もノンストップで取り組んできたので、気が狂いそうになり始めており、解決策はおそらく目の前にあると感じていますが、それを見ることができません。

編集: strncpy の代わりに memcpy を使用する必要があると誰かが指摘しました。私はそれを実行しましたが、テスト スクリプトはすべてのブロックが正しくないことを示しています。以前よりもさらに混乱しています...これがpastebinの新しい出力です。

編集 2 : 私はコンピューターに戻ってきて、もう一度見てきました。問題が発生している可能性がある場所を見つけるために、どこにでも print ステートメントを追加しているだけです。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 ステートメントは、渡されたプレーンテキストであると予想されるものを示しています。ただし、2 番目のステートメントは、完全に異なるものを示しており、同一である必要があります。私が完全に理解していない Cython で何かが起こっているようです。

4

2 に答える 2

2

ああ、私はこれをするのが嫌いです(自分の質問に答えてください)が、答えを見つけました:それは私が調べなければならないCythonの癖です(それが意図した癖なのか、それともバグです)。

問題は memcpy 行にあります。2 番目のパラメーターを <const_void*> にキャストします。これは pxd ファイルの Cython 定義と一致しますが、どうやら 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)

なんて奇妙な癖だ。正直なところ、どのキャストも同じ場所を指していると思いますが、キャストが動作にも影響を与える可能性があるようです。

于 2010-12-15T18:11:40.040 に答える
0

間違った初期化ベクトルの使用 (つまり、復号化と暗号化に異なる IV の使用) と Ciphermode の選択の組み合わせで何かおかしなことが起こったときに、これに似た結果に遭遇しました。健全性チェックとして、CBC から ECB に切り替えてみてください。

もう 1 つの可能性は、変数の 1 つが (新しい時間ベースのシードで) ランダム化されるべきではないときにランダム化されていることです。その場合、暗号化と復号化のステップの間に遅延を置くことで、データの破損がより頻繁に発生する可能性があります。

于 2010-12-15T16:48:47.397 に答える