Chia sẻ password
(a char[]
) và salt
(một byte[]
byte8 byte được chọn bởi một SecureRandom
loại muối tốt mà không cần phải giữ bí mật) với người nhận ngoài băng tần. Sau đó, để có được một chìa khóa tốt từ thông tin này:
/* 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");
Các số ma thuật (có thể được định nghĩa là hằng số ở đâu đó) 65536 và 256 lần lượt là số lần lặp đạo hàm chính và kích thước khóa.
Hàm phái sinh chính được lặp đi lặp lại để yêu cầu nỗ lực tính toán đáng kể và điều đó ngăn kẻ tấn công nhanh chóng thử nhiều mật khẩu khác nhau. Số lần lặp có thể được thay đổi tùy thuộc vào tài nguyên tính toán có sẵn.
Kích thước khóa có thể giảm xuống còn 128 bit, vẫn được coi là mã hóa "mạnh", nhưng nó không mang lại nhiều giới hạn an toàn nếu các cuộc tấn công được phát hiện làm suy yếu AES.
Được sử dụng với chế độ chuỗi khối thích hợp, cùng một khóa dẫn xuất có thể được sử dụng để mã hóa nhiều tin nhắn. Trong Chuỗi khối mã hóa (CBC) , một vectơ khởi tạo ngẫu nhiên (IV) được tạo cho mỗi thông báo, mang lại văn bản mã hóa khác nhau ngay cả khi văn bản thuần túy giống hệt nhau. CBC có thể không phải là chế độ an toàn nhất có sẵn cho bạn (xem AEAD bên dưới); có nhiều chế độ khác với các thuộc tính bảo mật khác nhau, nhưng tất cả chúng đều sử dụng một đầu vào ngẫu nhiên tương tự. Trong mọi trường hợp, đầu ra của mỗi hoạt động mã hóa là văn bản mã hóa và vectơ khởi tạo:
/* 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"));
Lưu trữ ciphertext
và iv
. Khi giải mã, dữ liệu SecretKey
được tạo lại theo cách chính xác, sử dụng mật khẩu có cùng tham số muối và lặp. Khởi tạo mật mã bằng khóa này và vectơ khởi tạo được lưu trữ với thông báo:
/* 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 bao gồm hỗ trợ API cho các chế độ mã hóa AEAD và nhà cung cấp "SunJCE" đi kèm với các bản phân phối OpenJDK và Oracle thực hiện các khởi đầu này với Java 8. Một trong những chế độ này được khuyến nghị mạnh mẽ thay cho CBC; nó sẽ bảo vệ tính toàn vẹn của dữ liệu cũng như quyền riêng tư của họ.
Một java.security.InvalidKeyException
với thông điệp "bất hợp pháp kích thước chìa khóa hoặc mặc định thông số" có nghĩa rằng sức mạnh mật mã được giới hạn; các tệp chính sách quyền lực pháp lý không giới hạn không ở đúng vị trí. Trong một JDK, chúng nên được đặt dưới${jdk}/jre/lib/security
Dựa trên mô tả sự cố, có vẻ như các tệp chính sách không được cài đặt chính xác. Các hệ thống có thể dễ dàng có nhiều thời gian chạy Java; kiểm tra kỹ để đảm bảo rằng vị trí chính xác đang được sử dụng.