Поділіться password
(a char[]
) та salt
( byte[]
8 байтів, вибраних SecureRandom
значком, що є доброю сіллю, яку не потрібно зберігати в таємниці) з одержувачем поза межами діапазону. Тоді, щоб отримати хороший ключ від цієї інформації:
/* Derive the key, given password and salt. */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Магічні числа (які десь можна визначити як константи) 65536 та 256 - це ітерація підрахунку ключових значень та розмір ключа відповідно.
Ключова функція деривації передбачає значні обчислювальні зусилля, і це не дозволяє зловмисникам швидко спробувати багато різних паролів. Кількість ітерацій може змінюватися залежно від наявних обчислювальних ресурсів.
Розмір ключа можна зменшити до 128 біт, що все ще вважається "сильним" шифруванням, але це не дає великої межі безпеки, якщо будуть виявлені атаки, які послаблюють AES.
Використовується у правильному режимі блокування ланцюга, той самий похідний ключ може бути використаний для шифрування багатьох повідомлень. У ланцюзі блоків шифрів (СРС) генерується випадковий вектор ініціалізації (IV) для кожного повідомлення, даючи різний текст шифру, навіть якщо звичайний текст однаковий. CBC може бути не найбільш безпечним для вас режимом (див. AEAD нижче); Є багато інших режимів з різними властивостями безпеки, але всі вони використовують подібний випадковий вхід. У будь-якому випадку, результатами кожної операції шифрування є текст шифру та вектор ініціалізації:
/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));
Зберігайте ciphertext
та iv
. При дешифруванні SecretKey
регенерується точно таким же чином, використовуючи пароль з однаковими параметрами солі та ітерації. Ініціалізуйте шифр за допомогою цього ключа та вектор ініціалізації, що зберігається з повідомленням:
/* Decrypt the message, given derived key and initialization vector. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
System.out.println(plaintext);
Java 7 включала підтримку API для шифруючих режимів AEAD , а постачальник "SunJCE", що входить до дистрибутивів OpenJDK та Oracle, реалізує це починаючи з Java 8. Один із цих режимів настійно рекомендується замість CBC; це захистить цілісність даних, а також їх конфіденційність.
java.security.InvalidKeyException
З повідомленням «Незаконні розмір ключа або по стандартних параметрів» означає , що сила криптографія є обмеженим; файли політики необмеженої юрисдикції не в правильному місці. У JDK вони повинні бути розміщені під${jdk}/jre/lib/security
На підставі опису проблеми здається, що файли політики неправильно встановлені. Системи можуть легко мати кілька режимів виконання Java; двічі перевірте, щоб переконатися, що використовується правильне місцеположення.