У меня есть тестовый инструмент, который использует Twofish в качестве алгоритма шифрования для шифрования данных перед отправкой на сервер. Код написан на C++ и использует оптимизированную реализацию C Bruce Schneier (https://www.schneier.com/code/twofish-optimized-c.zip). Мне нужно перенести этот инструмент на Python, и я использую модуль twofish (https://pypi.python.org/pypi/twofish/0.3.0). Я могу шифровать и расшифровывать строки длиной 16 символов, но для других длин строк он дает ошибку «ValueError: недопустимая длина блока».Twofish encryption in Python
Как я могу зашифровать & расшифровать большие данные с помощью модуля Twofish Python?
>>> 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
Update: Я пробуя другое решение этой проблемы. Я создал Windows DLL, twofish.dll из оптимизированной реализации C Bruce Schneier (https://www.schneier.com/code/twofish-optimized-c.zip). Кроме того, я экспортировал функции-обертки для кодирования & функции расшифровки члена с помощью __declspec (dllexport).
Я загружаю эту DLL в Python, используя ctype.CDLL. Прототип функции кодирования является:
__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
Для CBC для зашифрования данных произвольной длины требуется не только кратное размеру блока, но и для заполнения CBC, например PKCS # 5/PKCS # 7. –