Bagikan password
(a char[]
) dan salt
(a byte[]
—8 byte yang dipilih oleh a SecureRandom
menjadi garam yang baik — yang tidak perlu dirahasiakan) dengan penerima di luar jalur. Kemudian untuk mendapatkan kunci yang baik dari informasi ini:
/* 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");
Angka ajaib (yang dapat didefinisikan sebagai konstanta di suatu tempat) 65536 dan 256 adalah jumlah iterasi derivasi kunci dan ukuran kunci, masing-masing.
Fungsi derivasi kunci diulang untuk memerlukan upaya komputasi yang signifikan, dan yang mencegah penyerang dari cepat mencoba berbagai kata sandi yang berbeda. Hitungan iterasi dapat diubah tergantung pada sumber daya komputasi yang tersedia.
Ukuran kunci dapat dikurangi menjadi 128 bit, yang masih dianggap enkripsi "kuat", tetapi tidak memberikan banyak margin keamanan jika serangan ditemukan yang melemahkan AES.
Digunakan dengan mode blok-rantai yang tepat, kunci turunan yang sama dapat digunakan untuk mengenkripsi banyak pesan. Dalam Cipher Block Chaining (CBC) , vektor inisialisasi acak (IV) dihasilkan untuk setiap pesan, menghasilkan teks sandi yang berbeda bahkan jika teks biasa identik. CBC mungkin bukan mode paling aman yang tersedia untuk Anda (lihat AEAD di bawah); ada banyak mode lain dengan sifat keamanan berbeda, tetapi semuanya menggunakan input acak yang serupa. Bagaimanapun, output dari setiap operasi enkripsi adalah teks sandi dan vektor inisialisasi:
/* 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"));
Simpan ciphertext
dan iv
. Pada dekripsi, kode SecretKey
dibuat ulang dengan cara yang persis sama, menggunakan kata sandi dengan parameter garam dan iterasi yang sama. Inisialisasi sandi dengan kunci ini dan vektor inisialisasi yang tersimpan bersama pesan:
/* 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 menyertakan dukungan API untuk mode cipher AEAD , dan penyedia "SunJCE" yang disertakan dengan OpenJDK dan distribusi Oracle mengimplementasikannya dengan Java 8. Salah satu mode ini sangat disarankan sebagai pengganti CBC; itu akan melindungi integritas data serta privasi mereka.
Sebuah java.security.InvalidKeyException
dengan pesan "Ilegal ukuran kunci atau standar parameter" berarti bahwa kekuatan kriptografi yang terbatas; file kebijakan yurisdiksi kekuatan tidak terbatas tidak di lokasi yang benar. Dalam JDK, mereka harus ditempatkan di bawah${jdk}/jre/lib/security
Berdasarkan uraian masalah, sepertinya file kebijakan tidak diinstal dengan benar. Sistem dapat dengan mudah memiliki beberapa runtime Java; periksa kembali untuk memastikan bahwa lokasi yang benar sedang digunakan.