4

サーバーに送信する前にデータを暗号化するための暗号化アルゴリズムとして Twofish を使用するテスト ツールがあります。コードは C++ で書かれており、Bruce Schneier の最適化された C 実装 ( https://www.schneier.com/code/twofish-optimized-c.zip ) を使用しています。このツールを Python に移植する必要があり、twofish モジュール ( https://pypi.python.org/pypi/twofish/0.3.0 ) を使用しています。16 文字の長さの文字列を暗号化および復号化できますが、それ以外の文字列の長さの場合、「ValueError: 無効なブロックの長さ」というエラーが発生します。

Python の Twofish モジュールを使用して大きなデータを暗号化および復号化するにはどうすればよいですか?

>>> from twofish import Twofish
>>> key = binascii.unhexlify('8CACBE276491F6FF4B1EC0E9CFD52E76')
>>> t = Twofish(key)
>>> cipher_text = T.encrypt('deadbeaf12345678')
>>> plain_text = t.decrypt(cipher_text)
>>> plain_text
'deadbeaf12345678'
>>> cipher_text = t.encrypt('deadbeaf12345678hello world 1234')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/twofish.py", line 69, in encrypt
    raise ValueError('invalid block length')
ValueError: invalid block length

更新: この問題の別の解決策を試しています。Bruce Schneier の最適化された C 実装 ( https://www.schneier.com/code/twofish-optimized-c.zip )から Windows DLL である twofish.dll を作成しました。また、__declspec(dllexport) を使用して、エンコードおよびデコード メンバー関数のラッパー関数をエクスポートしました。

ctype.CDLL 関数を使用して、この DLL を Python にロードしています。エンコード関数のプロトタイプは次のとおりです。

__declspec(dllexport) int encode(unsigned char *key, unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int outbuflen, unsigned int& outlen)

Python スクリプトで引数の型を定義するにはどうすればよいですか?

import ctypes
import binascii
import requests

twofish_dll = ctypes.CDLL("twofish.dll")

encode = twofish_dll.encode

f = open('test.xml', 'r')
plain_text = f.read()
f.close()

cipher_text = ctypes.create_string_buffer(8192)
cipher_text_lenght = (ctypes.c_uint)()

KCS = '8CACBE276491F6FF4B1EC0E9CFD52E76'
key = binascii.unhexlify(KCS)

encode.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint, ctypes.c_char_p, ctypes.c_uint, ctypes.POINTER(ctypes.c_uint)]
encode(ctypes.c_char_p(key), ctypes.c_char_p(plain_text), len(plain_text), cipher_text, 8192, ctypes.byref(cipher_text_lenght))

上記のコードを実行すると、以下のエラーがスローされます。

Traceback (most recent call last):
  File "C:\Data\sepm_test.py", line 21, in <module>
    encode(ctypes.c_char_p(key), ctypes.c_char_p(plain_text), len(plain_text), cipher_text, 8192, ctypes.byref(cipher_text_lenght))
TypeError: bytes or integer address expected instead of str instance
4

3 に答える 3

2

Twofish は、一度に 16 オクテットしか暗号化しないブロック暗号です。ドキュメントを引用します:

キーの長さが [0, 32] の twofish.Twofish インスタンスを作成し、16 バイト ブロックで暗号化メソッドと復号化メソッドを使用します。

すべての値はバイナリ文字列でなければなりません (Python 2 では str、Python 3 ではバイト)

[警告] これは、CTR や CBC などの実用的な暗号モードで使用する必要があります。これが何を意味するのかわからない場合は、おそらくより高いレベルのライブラリを使用する必要があります。

警告に注意してください。CBC や CTR はロケット科学ではありませんが、Twofish を素朴に使用すると、そのセキュリティはひどく損なわれます。

于 2015-03-25T01:48:31.230 に答える