Какую библиотеку AES использовать в Ruby / Python?

Мне нужно иметь возможность отправлять зашифрованные данные между клиентом Ruby и сервером Python (и наоборот), и у меня возникли проблемы с ruby-aes гем / библиотека. Библиотека очень проста в использовании, но у нас возникли проблемы с передачей данных между ней и библиотекой pyCrypto AES для Python. Эти библиотеки кажутся хорошими, когда используются только они, но они, похоже, не очень хорошо работают через языковые границы. Любые идеи?

Изменить: мы осуществляем связь через SOAP, а также пытались преобразовать двоичные данные в base64, но безрезультатно. Кроме того, более важно, что шифрование / дешифрование почти, но не совсем одинаковое между двумя (например, длина отличается на один или в конце расшифрованной строки есть лишние символы мусора)


person Chris Bunch    schedule 13.10.2008    source источник
comment
Название вопроса немного вводит в заблуждение, учитывая, что ни один из ответов не касается того, какие библиотеки использовать. Так лучше: stackoverflow.com/questions/172486/   -  person wsorenson    schedule 14.09.2009


Ответы (5)


(например, длина отличается на один или в конце расшифрованной строки есть лишние символы мусора)

Я пропустил это. Нет ничего плохого в вашем шифровании / дешифровании. Похоже на проблему с заполнением. AES всегда кодирует данные блоками по 128 бит. Если длина ваших данных не кратна 128 битам, данные должны быть дополнены перед шифрованием, а заполнение необходимо удалить / игнорировать после шифрования.

person a2800276    schedule 13.10.2008
comment
Да, оказалось, что по сути так оно и было. - person Chris Bunch; 13.10.2008

Оказывается, произошло то, что ruby-aes автоматически заполняет данные, чтобы заполнить 16 символов, и вставляет нулевой символ в конце последней строки в качестве разделителя. PyCrypto требует, чтобы вы делали символы, кратные 16, так что мы выяснили, что делает ruby-aes.

person Chris Bunch    schedule 13.10.2008

Без дополнительной информации сложно даже догадаться, что происходит ...

На вашем месте я бы проверил это в ваших программах на Python и Ruby:

  1. Ключи те же (очевидно). Выгрузите их как шестнадцатеричные и сравните каждый байт.
  2. Векторы инициализации такие же. Это параметр IV в AES.new() в pyCrypto. Сбросьте их тоже как шестнадцатеричные.
  3. Режимы такие же. Параметр mode в AES.new() в pyCrypto.

В pyCrypto есть значения по умолчанию для IV и mode, но не верьте, что они такие же, как в реализации Ruby. Используйте один из более простых режимов, например CBC. Я обнаружил, что разные библиотеки по-разному интерпретируют работу сложных режимов режима, таких как PTR.

В Википедии есть отличная статья о том, как блокировать режимы шифрования.

person HughE    schedule 13.10.2008
comment
Да, клавиши, IV и режимы одинаковы. См. Мой ответ, чтобы узнать, в чем проблема. - person Chris Bunch; 13.10.2008

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

f = open('/path/to/file', 'rb')

Буква «b» обозначает двоичный код. И если вы записываете зашифрованные данные в файл из Python:

f = open('/path/to/file', 'wb')
f.write(encrypted_data)
person mhawke    schedule 13.10.2008
comment
Спасибо, но в данном случае мы делаем это через серверы SOAP. Я думаю, что есть аналогичный аналог, но для SOAP вместо двоичных файлов. - person Chris Bunch; 13.10.2008
comment
Как зашифрованные (двоичные) данные инкапсулируются в пакет SOAP? Для меня это больше похоже на проблему с SOAP. Возможно, вам стоит добавить больше деталей к вопросу. - person mhawke; 13.10.2008
comment
Вы можете устранить проблемы с языком и / или библиотекой шифрования между Ruby и Python, пытаясь записать в двоичный файл с одного языка, а затем расшифровать его с помощью другого. Если это сработает, посмотрите на транспортный уровень. - person mhawke; 13.10.2008

В основном то, что сказал Хью выше: проверьте IV, размеры ключей и режимы цепочки, чтобы убедиться, что все идентично.

Протестируйте обе стороны независимо, закодируйте некоторую информацию и убедитесь, что Ruby и Python добавили ее одинаково. Вы предполагаете, что проблема связана с шифрованием, но это может быть что-то столь же простое, как отправка зашифрованных данных с помощью puts, которое выбрасывает в данные случайные символы новой строки. Убедившись, что они правильно зашифровывают данные, убедитесь, что вы получаете именно то, что, по вашему мнению, отправили. Продолжайте шаг за шагом, пока не найдете этап, который искажает данные.

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

person a2800276    schedule 13.10.2008