Apa yang salah dengan contoh berikut?
Masalahnya adalah bahwa bagian pertama dari string yang didekripsi itu tidak masuk akal. Namun, sisanya baik-baik saja, saya mendapatkan ...
Result: `£eB6O�geS��i are you? Have a nice day.
@Test
public void testEncrypt() {
try {
String s = "Hello there. How are you? Have a nice day.";
// Generate key
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey aesKey = kgen.generateKey();
// Encrypt cipher
Cipher encryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, aesKey);
// Encrypt
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, encryptCipher);
cipherOutputStream.write(s.getBytes());
cipherOutputStream.flush();
cipherOutputStream.close();
byte[] encryptedBytes = outputStream.toByteArray();
// Decrypt cipher
Cipher decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(aesKey.getEncoded());
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);
// Decrypt
outputStream = new ByteArrayOutputStream();
ByteArrayInputStream inStream = new ByteArrayInputStream(encryptedBytes);
CipherInputStream cipherInputStream = new CipherInputStream(inStream, decryptCipher);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = cipherInputStream.read(buf)) >= 0) {
outputStream.write(buf, 0, bytesRead);
}
System.out.println("Result: " + new String(outputStream.toByteArray()));
}
catch (Exception ex) {
ex.printStackTrace();
}
}
java
encryption
aes
TedTrippin
sumber
sumber
Jawaban:
Banyak orang termasuk saya menghadapi banyak masalah dalam membuat ini berfungsi karena kehilangan beberapa informasi seperti, lupa mengonversi ke Base64, vektor inisialisasi, kumpulan karakter, dll. Jadi saya berpikir untuk membuat kode yang berfungsi penuh.
Semoga bermanfaat bagi Anda semua: Untuk mengkompilasi Anda memerlukan jar Codec Apache Commons tambahan, yang tersedia di sini: http://commons.apache.org/proper/commons-codec/download_codec.cgi
sumber
System.out.println("encrypted string:" + DatatypeConverter.printBase64Binary(encrypted));
byte[] original = cipher.doFinal(DatatypeConverter.parseBase64Binary(encrypted));
SecureRandom
Berikut solusi tanpa
Apache Commons Codec
'sBase64
:Contoh penggunaan:
Cetakan:
sumber
encrypt(String)
dan bukanencrypt(byte[] )
?. Enkripsi (dekripsi juga) adalah proses berbasis byte (bagaimanapun juga AES). Enkripsi mengambil byte sebagai input, dan output byte, begitu pula dekripsi (contoh kasus:Cipher
objek melakukannya). Sekarang, satu kasus penggunaan tertentu mungkin memiliki byte terenkripsi yang berasal dari String, atau dikirim sebagai String (lampiran MIME base64 untuk Mail ...), tetapi itu adalah masalah encoding byte, yang di dalamnya terdapat ratusan solusi, sama sekali tidak terkait dengan AES / enkripsi.Strings
karena pada dasarnya itulah 95% saya bekerja dengan waktu dan Anda akhirnya tetap berkonversi.Menurut saya Anda tidak berurusan dengan benar dengan Inisialisasi Vektor (IV). Sudah lama sekali sejak terakhir kali saya membaca tentang AES, IV, dan rantai blok, tetapi kalimat Anda
sepertinya tidak baik-baik saja. Dalam kasus AES, Anda dapat menganggap vektor inisialisasi sebagai "status awal" dari cipher instance, dan status ini adalah sedikit informasi yang tidak dapat Anda peroleh dari kunci Anda, tetapi dari komputasi sebenarnya dari sandi yang mengenkripsi. (Seseorang dapat berargumen bahwa jika IV dapat diekstraksi dari kunci, maka itu tidak akan berguna, karena kunci tersebut sudah diberikan ke contoh cipher selama fase init).
Oleh karena itu, Anda harus mendapatkan IV sebagai byte [] dari cipher instance di akhir enkripsi Anda
dan Anda harus menginisialisasi
Cipher
inDECRYPT_MODE
dengan byte ini []:Kemudian, dekripsi Anda akan baik-baik saja. Semoga ini membantu.
sumber
IV yang Anda gunakan untuk dekripsi salah. Ganti kode ini
Dengan kode ini
Dan itu seharusnya menyelesaikan masalah Anda.
Di bawah ini termasuk contoh kelas AES sederhana di Java. Saya tidak menyarankan penggunaan kelas ini di lingkungan produksi, karena mungkin tidak memperhitungkan semua kebutuhan khusus aplikasi Anda.
Perhatikan bahwa AES tidak ada hubungannya dengan pengkodean, itulah sebabnya saya memilih untuk menanganinya secara terpisah dan tanpa perlu pustaka pihak ketiga.
sumber
"/NoPadding"
. CTR adalah mode yang mengubah AES menjadi stream cipher, dan stream cipher beroperasi pada byte, bukan blok.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.
Penting:
SecureRandom
2. Buat Vektor Inisialisasi
Sebuah vektor inisialisasi (IV) digunakan sehingga kunci rahasia yang sama akan menciptakan berbagai teks cipher .
Penting:
SecureRandom
3. Enkripsi dengan IV dan Key
Penting:
CipherInputStream
saat mengenkripsi potongan data yang besarcipher.updateAAD(associatedData);
Lainnya di sini.3. Menyambung ke Pesan Tunggal
Cukup tambahkan IV dan ciphertext. Seperti disebutkan di atas, infus tidak perlu dirahasiakan.
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:
4. Siapkan Dekripsi: Deserialisasi
Jika Anda telah mengkodekan pesan, pertama-tama decode ke dalam byte array:
Penting:
5. Dekripsi
Inisialisasi cipher dan setel parameter yang sama seperti dengan enkripsi:
Penting:
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 .
sumber
this is true for CBC mode but not for GCM
maksud Anda seluruh bagian, atau hanya itu yang tidak benar-benar perlu tidak terduga?Versi Editor Online Runnable: -
sumber
Seringkali merupakan ide yang baik untuk mengandalkan solusi yang disediakan pustaka standar:
Ini mencetak "Teks untuk dikodekan".
Solusi didasarkan pada Panduan Referensi Arsitektur Kriptografi Java dan https://stackoverflow.com/a/20591539/146745 jawaban.
sumber
Ini merupakan peningkatan dari jawaban yang diterima.
Perubahan:
(1) Menggunakan IV acak dan menambahkannya ke teks terenkripsi
(2) Menggunakan SHA-256 untuk menghasilkan kunci dari frasa sandi
(3) Tidak ada ketergantungan pada Apache Commons
sumber
Solusi lain menggunakan java.util.Base64 dengan Spring Boot
Kelas Encryptor
Kelas EncryptorController
application.properties
Contoh
http: // localhost: 8082 / cipher / encrypt / jmendoza
2h41HH8Shzc4BRU3hVDOXA ==
http: // localhost: 8082 / cipher / decrypt / 2h41HH8Shzc4BRU3hVDOXA ==
jmendoza
sumber
Versi yang dioptimalkan dari jawaban yang diterima.
tidak ada libs pihak ketiga
memasukkan IV ke dalam pesan terenkripsi (bisa publik)
panjang sandi bisa berapa saja
Kode:
Pemakaian:
Contoh keluaran:
sumber
e.printStackTrace()
dalam apa yang disebut kode yang dioptimalkan.