Dalam jawaban ini saya memilih untuk mendekati tema utama "Contoh enkripsi / dekripsi AES Java Sederhana" dan bukan pertanyaan debugging spesifik karena menurut saya ini akan menguntungkan sebagian besar pembaca.
Ini adalah ringkasan sederhana dari posting blog saya tentang enkripsi AES di Java, jadi saya sarankan untuk membacanya sebelum menerapkan apa pun. Namun saya masih akan memberikan contoh sederhana untuk digunakan dan memberikan beberapa petunjuk apa yang harus diperhatikan.
Dalam contoh ini saya akan memilih untuk menggunakan enkripsi terotentikasi dengan Galois / Counter Mode atau GCM mode. Alasannya adalah bahwa dalam banyak kasus Anda menginginkan integritas dan keaslian yang dikombinasikan dengan kerahasiaan (baca lebih lanjut di blog ).
Tutorial Enkripsi / Dekripsi AES-GCM
Berikut adalah langkah-langkah yang diperlukan untuk mengenkripsi / mendekripsi dengan AES-GCM dengan Java Cryptography Architecture (JCA) . Jangan gabungkan dengan contoh lain , karena perbedaan kecil dapat membuat kode Anda benar-benar tidak aman.
1. Buat Kunci
Karena itu tergantung pada kasus penggunaan Anda, saya akan menganggap kasus paling sederhana: kunci rahasia acak.
SecureRandom secureRandom = new SecureRandom();
byte[] key = new byte[16];
secureRandom.nextBytes(key);
SecretKey secretKey = SecretKeySpec(key, "AES");
Penting:
2. Buat Vektor Inisialisasi
Sebuah vektor inisialisasi (IV) digunakan sehingga kunci rahasia yang sama akan menciptakan berbagai teks cipher .
byte[] iv = new byte[12]; //NEVER REUSE THIS IV WITH SAME KEY
secureRandom.nextBytes(iv);
Penting:
3. Enkripsi dengan IV dan Key
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec parameterSpec = new GCMParameterSpec(128, iv); //128 bit auth tag length
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] cipherText = cipher.doFinal(plainText);
Penting:
- menggunakan tag otentikasi 16 byte / 128 bit (digunakan untuk memverifikasi integritas / keaslian)
- tag otentikasi akan secara otomatis ditambahkan ke teks sandi (dalam implementasi JCA)
- karena GCM berperilaku seperti stream cipher, tidak diperlukan padding
- digunakan
CipherInputStream
saat mengenkripsi potongan data yang besar
- ingin data tambahan (non-rahasia) diperiksa jika diubah? Anda mungkin ingin menggunakan data terkait dengan
cipher.updateAAD(associatedData);
Lainnya di sini.
3. Menyambung ke Pesan Tunggal
Cukup tambahkan IV dan ciphertext. Seperti disebutkan di atas, infus tidak perlu dirahasiakan.
ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + cipherText.length);
byteBuffer.put(iv);
byteBuffer.put(cipherText);
byte[] cipherMessage = byteBuffer.array();
Secara opsional, enkode dengan Base64 jika Anda memerlukan representasi string. Gunakan implementasi bawaan Android atau Java 8 (jangan gunakan Apache Commons Codec - ini implementasi yang buruk). Encoding digunakan untuk "mengubah" array byte menjadi representasi string agar ASCII aman, misalnya:
String base64CipherMessage = Base64.getEncoder().encodeToString(cipherMessage);
4. Siapkan Dekripsi: Deserialisasi
Jika Anda telah mengkodekan pesan, pertama-tama decode ke dalam byte array:
byte[] cipherMessage = Base64.getDecoder().decode(base64CipherMessage)
Penting:
5. Dekripsi
Inisialisasi cipher dan setel parameter yang sama seperti dengan enkripsi:
final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
//use first 12 bytes for iv
AlgorithmParameterSpec gcmIv = new GCMParameterSpec(128, cipherMessage, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmIv);
//use everything from 12 bytes on as ciphertext
byte[] plainText = cipher.doFinal(cipherMessage, 12, cipherMessage.length - 12);
Penting:
- jangan lupa untuk menambahkan data yang terkait dengan
cipher.updateAAD(associatedData);
jika Anda menambahkan selama enkripsi.
Cuplikan kode yang berfungsi dapat ditemukan di inti ini.
Perhatikan bahwa implementasi Android (SDK 21+) dan Java (7+) terbaru harus memiliki AES-GCM. Versi lama mungkin kekurangannya. Saya tetap memilih mode ini, karena lebih mudah diimplementasikan selain lebih efisien dibandingkan dengan mode serupa dari Encrypt-then-Mac (misalnya AES-CBC + HMAC ). Lihat artikel ini tentang cara menerapkan AES-CBC dengan HMAC .