Нет, вам не нужна соль, и ваш ключ в порядке. Режим CBC требует IV (вектор инициализации), см. Википедию , и IV должен быть разным для каждого зашифрованного фрагмента данных, но для каждого дешифрования должно использоваться то же значение, что и для соответствующего шифрования,(добавлено) Для Си-би-си, хотя и не для некоторых других режимов, для безопасности также важно, чтобы противник не предсказывал IV;Самый простой и наиболее распространенный способ достижения как уникальности, так и непредсказуемости - это использовать безопасный генератор случайных чисел (он же бит), такой как Java SecureRandom
. Если вы хотите узнать о других методах, это не является проблемой программирования и лучше подходит для crypto.SX или security.SX, где уже есть несколько Qs.
Вы можете либо сгенерировать IV явно и указать его для шифрования и дешифрования, либо разрешить операции шифрования генерировать сам IV, извлечь его из зашифрованного шифра и указать его для дешифрования шифра. В любом случае шифровщик должен предоставить значение, которое будет использовать расшифровщик;Обычный подход состоит в том, чтобы просто объединить IV с зашифрованным текстом (что позволяет очень легко поддерживать их соответствие), но опять же есть другие подходы, обсуждаемые в области криптографии и безопасности. См. https://docs.oracle.com/en/java/javase/11/security/java-cryptography-architecture-jca-reference-guide.html в разделах «Инициализация объекта шифрования» (два абзаца сразу после блока описаний методов в штучной упаковке) и «Управление параметрами алгоритма».
Также не храните зашифрованный текст в String
. Java String
предназначена для обработки допустимых символов, а не произвольных байтов. «Декодирование» зашифрованного текста в строку и «кодирование» его обратно в двоичный код почти всегда приведет к потере или изменению некоторых данных, особенно если вы позволите Charset различаться на двух концах, а в современной криптографии - любое изменение в зашифрованном тексте. уничтожит все или большую часть ваших данных. Поскольку зашифрованный текст составляет байт, лучше всего обрабатывать его как byte[]
;если это невозможно, потому что вы хотите поместить его в то, что равно символам, таким как URL, используйте одну из многих схем, разработанных для кодирования произвольных байтов в текст, чтобы их можно было правильно восстановить: base64 (3или 4 основных варианта, плюс много второстепенных), base32, шестнадцатеричное / base16, кодирование URL-адреса в процентах, MIME, цитируемый для печати, yencode, Kermit, PPP и т. д. j8 + java.util.Base64
предоставляет более новую base64варианты (т. е. не uuencode).
И наоборот, хотя «открытый текст» в современной криптографии действительно может быть любой формой данных, если ваш действительно текст и принадлежит к String
, вам следуетзакодируйте его с помощью подходящего Charset перед шифрованием и декодируйте, используя то же самое Charset после расшифровки, то есть
byte[] ctext = encCipher.doFinal (input.getBytes(charset));
...
String output = new String (decCipher.doFinal (ctext), charset);
Хотя «лучший» Charset может отличаться в зависимости от ваших данных, если вы неНе знаю, какими будут данные, или не хотите их анализировать, UTF-8
достаточно хорош для большинства текстовых данных и очень популярен и стандартен.