Есть отступ и цепочка . Сначала вы должны получить правильную цепочку.
AES шифрует блоки по 16 байт, не больше и не меньше. Если вы хотите зашифровать сообщение, которое может быть длиннее 16 байт, вам нужно решить, как данные будут разбиты на блоки и затем собраны заново. Основной алгоритм разделения называется ECB : это «просто разделение» на блоки, зашифрованные индивидуально. Известно, что ECB является слабым с данными реального мира, потому что он пропускает информацию о том, какие блоки открытого текста равны друг другу (они будут одинаково зашифрованы), и такая избыточность часто возникает в «нормальных» данных.
Таким образом, необходимо каким-то образом «рандомизировать» блоки данных, чтобы избыточность данных была скрыта. Режим CBC выполняет это посредством «цепочки»: обработка блока зависит от результата шифрования предыдущего блока. А именно, блок открытого текста для шифрования объединяется (с побитовым XOR) с выводом предыдущего блока шифрования.
Важным моментом здесь является то, что первый блок для шифрования (первые 16 байтов данных) не имеет «предыдущего блока», поэтому XOR не имеет ничего общего с. Это решается путем выбора «случайного IV», то есть последовательности из 16 случайных байтов, которая будет использоваться в качестве «блока -1» для этапа XORing. IV должен быть известен расшифровывающей стороне (иначе он не будет знать, с чем XOR расшифрованный блок, и первые 16 байтов данных не будут понятны). Яркая сторона в том, что IV не должен быть секретным; он ДОЛЖЕН быть выбран равномерно (это не может быть счетчик, увеличенный для каждого сообщения), но он может быть передан «в открытом виде», обычно вдоль самого зашифрованного сообщения.
Так что вам нужно немного побеспокоиться о IV, и я ничего не вижу в коде Java или Ruby. Обычно в Java по умолчанию используется ECB (следовательно, IV вообще нет). Если в CBC по умолчанию используется значение «все ноль» в CBC (что концептуально небезопасно), то вполне нормально, что вы можете расшифровать первый блок (записать его, он «просто работает»), но в равной степени нормально что он не работает для последующих блоков.
Поэтому я предлагаю вам явно использовать CBC (в Java используйте "AES/CBC/PKCS5Padding"
в качестве имени алгоритма, а не "AES"
) и управлять IV (который затем должен быть передан; вы можете принять соглашение для объединения IV непосредственно перед зашифрованное сообщение).
Несколько других заметок:
Заполнение - это добавление некоторых данных в открытый текст, чтобы у вас была подходящая длина ввода. CBC требует, чтобы длина ввода была кратна размеру блока (16 байт). PKCS # 5 - это популярный метод, при котором вы добавляете не менее 1 байта, не более 16 байтов, так что все они имеют значение n , где n - это число добавлены байты. Затем получатель может узнать (однозначно), сколько байтов было добавлено, и удалить их. Java может добавить заполнение для вас, и я полагаю, что Ruby также может автоматически обработать заполнение, если вас попросят.
В коде Java вы используете key.getBytes()
. Я полагаю, что key
является String
. Помните, что getBytes()
кодирует строку в соответствии с набором символов платформы по умолчанию, который не всегда одинаков во всем мире Вы сэкономите немного беспокойства, указав явную кодировку. Кроме того, поскольку вы хотите использовать 128-битный ключ, но вы получаете что-то на стороне Ruby только с "AES-256", то я предполагаю, что вы на самом деле используете 256-битный ключ на стороне Java. Я предполагаю, что ваша строка key
представляет собой шестнадцатеричное представление вашего ключа в виде 32 символов. key.getBytes()
не интерпретирует шестнадцатеричные цифры; он кодирует сами символы, получая 32-байтовый массив - и 32 байта, то есть 256 бит, а не 128.