Мне нужно реализовать 256-битное шифрование AES, но все примеры, которые я нашел в Интернете, используют «KeyGenerator» для генерации 256-битного ключа, но я бы хотел использовать свой собственный пароль. Как я могу создать свой собственный ключ? Я попытался дополнить его до 256 бит, но затем я получаю сообщение об ошибке, говорящее о том, что ключ слишком длинный. У меня установлен патч неограниченной юрисдикции, так что это не проблема :)
То есть. KeyGenerator выглядит так ...
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
РЕДАКТИРОВАТЬ
Я на самом деле дополнял пароль до 256 байтов, а не бит, что слишком долго. Ниже приведен код, который я использую сейчас, когда у меня есть немного опыта с этим.
byte[] key = null; // TODO
byte[] input = null; // TODO
byte[] output = null;
SecretKeySpec keySpec = null;
keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
output = cipher.doFinal(input)
Биты "TODO" нужно делать самостоятельно :-)
java
encryption
cryptography
passwords
aes
Nippysaurus
источник
источник
Ответы:
Поделитесь
password
(achar[]
) иsalt
(a -byte[]
8 байтов, выбранных символом a,SecureRandom
- хорошей солью, которую не нужно хранить в секрете) с получателем вне диапазона. Затем, чтобы получить хороший ключ из этой информации:Магические числа (которые могут быть определены как константы где-то) 65536 и 256 - это количество итераций вывода ключа и размер ключа соответственно.
Функция получения ключа повторяется, чтобы потребовать значительных вычислительных усилий, и это не позволяет злоумышленникам быстро пробовать много разных паролей. Количество итераций может быть изменено в зависимости от доступных вычислительных ресурсов.
Размер ключа может быть уменьшен до 128 бит, который все еще считается «сильным» шифрованием, но он не дает большой запас прочности, если обнаружены атаки, которые ослабляют AES.
При использовании с надлежащим режимом цепочки блоков один и тот же производный ключ может использоваться для шифрования многих сообщений. В Cipher Block Chaining (CBC) случайный вектор инициализации (IV) генерируется для каждого сообщения, давая различный зашифрованный текст, даже если обычный текст идентичен. CBC может быть не самым безопасным режимом, доступным для вас (см. AEAD ниже); Есть много других режимов с различными свойствами безопасности, но все они используют одинаковый случайный ввод. В любом случае выходные данные каждой операции шифрования представляют собой зашифрованный текст и вектор инициализации:
Храните
ciphertext
иiv
. При дешифровании,SecretKey
регенерируется точно так же, используя пароль с теми же параметрами соли и итерации. Инициализируйте шифр с этим ключом и вектором инициализации, сохраненным с сообщением:Java 7 включала поддержку API для режимов шифрования AEAD , и поставщик SunJCE, включенный в дистрибутивы OpenJDK и Oracle, реализует их начиная с Java 8. Один из этих режимов настоятельно рекомендуется вместо CBC; это защитит целостность данных, а также их конфиденциальность.
java.security.InvalidKeyException
С сообщением «Незаконные размер ключа или по умолчанию параметров» означает , что сила криптография является ограниченным; файлы политики неограниченной юрисдикции находятся не в правильном месте. В JDK они должны быть помещены под${jdk}/jre/lib/security
Судя по описанию проблемы, похоже, что файлы политики установлены неправильно. Системы могут легко иметь несколько сред выполнения Java; перепроверьте, чтобы убедиться, что используется правильное местоположение.
источник
PBEwith<prf>and<encryption>
алгоритмов; например, SunJCE не предоставляет и PBE для AES. Во-вторых, включение jasypt не является целью. Пакет, который подразумевает обеспечение безопасности без понимания основополагающих принципов, кажется опасным prima facie.tmp.getEncoded()
как хеш. Вы также должны сохранитьsalt
и итерации (65536 в этом примере), чтобы вы могли пересчитать хэш, когда кто-то пытается аутентифицироваться. В этом случае генерируйте соль с помощью криптографического генератора случайных чисел при каждом изменении пароля.Рассмотрите возможность использования крипто-модуля Spring Security.
Это обеспечивает простую абстракцию для шифрования и, кажется, соответствует тому, что требуется здесь,
Взгляд на внутренности показывает структуру, похожую на ответ Эриксона .
Как отмечалось в этом вопросе, для этого также требуется политика неограниченной юрисдикции расширения шифрования Java (JCE) (иначе вы столкнетесь
InvalidKeyException: Illegal Key Size
). Это загружаемое для Java 6 , Java 7 и Java 8 .Пример использования
И образец вывода,
источник
NULL_IV_GENERATOR
Используется утилитой Spring не является безопасным. Если приложение не предоставляет IV, пусть поставщик выберет его и запросит его после инициализации.Прочитав предложения Эриксона и собрав все, что я мог, из пары других публикаций и этого примера здесь , я попытался обновить код Дуга с рекомендуемыми изменениями. Не стесняйтесь редактировать, чтобы сделать это лучше.
Некоторые примечания: при этом используется 128-битный ключ шифрования - очевидно, java не будет выполнять 256-битное шифрование "из коробки". Реализация 256 требует установки некоторых дополнительных файлов в каталог установки Java.
Кроме того, я не крипто-человек. Берегись.
источник
printStackTrace()
CipherInputStream
иCipherOutputStream
не является большой проблемой. Перетасовка всех исключений под таблицей является проблемой. Тот факт, что соль внезапно стала полем и что требуется IV, является проблемой. Тот факт, что он не следует соглашениям Java-кодирования, является проблемой. И тот факт, что это работает только с файлами, пока об этом не просили, является проблемой. И то, что остальная часть кода в основном является копией, тоже не помогает. Но , возможно , я настроить его , чтобы сделать его лучше, как это было предложено ...Создать собственный ключ из байтового массива очень просто:
Но создания 256-битного ключа недостаточно. Если генератор ключей не может сгенерировать для вас 256-битные ключи, то,
Cipher
вероятно, класс также не поддерживает 256-битную AES. Вы говорите, что у вас установлено исправление неограниченной юрисдикции, поэтому должен поддерживаться шифр AES-256 (но тогда должны быть и 256-битные ключи, так что это может быть проблемой конфигурации).Обходной путь для отсутствия поддержки AES-256 заключается в том, чтобы взять некоторую свободно доступную реализацию AES-256 и использовать ее в качестве пользовательского поставщика. Это включает в себя создание собственного
Provider
подкласса и использование его сCipher.getInstance(String, Provider)
. Но это может быть сложным процессом.источник
Cipher
, а не в самом поставщике. Вы можете использовать AES-256 в Java 8 и ниже, но вам нужно использовать собственный API. Или среда выполнения, которая не накладывает ограничений на размер ключа, конечно.В прошлом я делал хеширование ключа через что-то вроде SHA256, затем извлекал байты из хэша в байт ключа [].
После того, как у вас есть ваш байт [], вы можете просто сделать:
источник
Cipher aes256 = Cipher.getInstance("AES/OFB/NoPadding"); MessageDigest keyDigest = MessageDigest.getInstance("SHA-256"); byte[] keyHash = keyDigest.digest(secret.getBytes("UTF-8")); SecretKeySpec key = new SecretKeySpec(keyHash, "AES"); aes256.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(initializationVector));
Я также делаю то же самое, что было предложено в вашем ответе, но я все еще получаю исключение java.security.InvalidKeyException: Недопустимый размер ключа Обязательно ли загружать файл политики JCE?В дополнение к правкам @ Wufoo, следующая версия использует InputStreams, а не файлы, чтобы упростить работу с различными файлами. Он также хранит IV и Salt в начале файла, что позволяет отслеживать только пароль. Поскольку IV и Соль не должны быть секретными, это делает жизнь немного легче.
источник
(Может быть полезно для других с аналогичным требованием)
У меня было похожее требование использовать
AES-256-CBC
шифрование и дешифрование в Java.Для достижения (или определения) 256-байтового шифрования / дешифрования
Java Cryptography Extension (JCE)
политика должна быть установлена на"Unlimited"
Это может быть установлено в
java.security
файле в разделе$JAVA_HOME/jre/lib/security
(для JDK) или$JAVA_HOME/lib/security
(для JRE)crypto.policy=unlimited
Или в коде как
В Java 9 и более поздних версиях эта функция включена по умолчанию.
источник
Подумайте об использовании Encryptor4j, автором которого я являюсь.
Прежде чем продолжить, убедитесь, что у вас установлены файлы Политики неограниченной юрисдикции, чтобы вы могли использовать 256-битные ключи AES.
Затем сделайте следующее:
Теперь вы можете использовать шифратор для шифрования вашего сообщения. Вы также можете выполнить потоковое шифрование, если хотите. Он автоматически генерирует и добавляет безопасный IV для вашего удобства.
Если это файл, который вы хотите сжать, взгляните на этот ответ. Шифрование большого файла в AES с использованием JAVA для еще более простого подхода.
источник
Используйте этот класс для шифрования. Оно работает.
И это ivBytes и случайный ключ;
источник