Dekripsi Java menimbulkan pengecualian

Inilah metode enkripsi saya (nilai adalah parameter input):

 byte key_bytes[] = "12345678".getBytes();
 SecretKeySpec _keyspec = new SecretKeySpec(key_bytes, "DES");
 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // Yes, I know I shouldn't use DES
 cipher.init(Cipher.ENCRYPT_MODE, _keyspec);

 byte[] utf8 = value.getBytes("UTF8");
 byte[] enc = cipher.doFinal(utf8);   // Encrypt

 String encrypted = new String(new Base64().encode(enc));

 return URLEncoder.encode(encrypted, "UTF-8");

Inilah metode dekripsi saya (nilai adalah parameter input):

byte key_bytes[] = "12345678".getBytes();
SecretKeySpec _keyspec = new SecretKeySpec(key_bytes, "DES");
Cipher dcipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
dcipher.init(Cipher.DECRYPT_MODE, _keyspec);

byte[] dec = new Base64().decode(value);
byte[] utf8 = dcipher.doFinal(dec);  // Decrypt, throws exception
return new String(utf8, "UTF8");

Dan saya mendapat Pengecualian:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

Saya telah membaca topik yang berbeda, jadi saya menemukan, bahwa pengecualian ini terjadi, ketika tidak ada padding dan ada mode sandi lain. Jadi, apa yang salah?


person John Smith    schedule 17.07.2014    source sumber
comment
Dimana URLDecodermu? Dan ini terutama terjadi jika ciphertext Anda bukan lagi kelipatan ukuran blok (8 untuk DES).   -  person Maarten Bodewes    schedule 17.07.2014
comment
Perhatikan bahwa penggunaan DES tidak aman, ECB tidak aman dan mengirimkan teks tersandi tanpa tag otentikasi (HMAC) melalui jaringan juga tidak aman.   -  person Maarten Bodewes    schedule 18.07.2014
comment
Saya sebutkan bahwa DES tidak aman, ECB tidak aman, tetapi persyaratan tetaplah persyaratan   -  person John Smith    schedule 18.07.2014
comment
@JohnSmith Periksa lagi jawaban dan komentar saya yang diperbarui.   -  person Wundwin Born    schedule 18.07.2014
comment
@owlstead bisakah Anda memberikan contoh penggunaan HMAC dengan jenis enkripsi seperti itu?   -  person John Smith    schedule 18.07.2014
comment
Nah, Anda menggunakan - sebaiknya yang berbeda - kunci untuk perhitungan HMAC, kemudian menghitung HMAC atas ciphertext dan - jika digunakan - IV dan parameter enkripsi dikonfigurasi lainnya yang dikirim. Kemudian Anda memverifikasi HMAC sebelum dekripsi. Itu benar.   -  person Maarten Bodewes    schedule 18.07.2014
comment
@owlstead terima kasih atas saran Anda, saya akan mengingatnya   -  person John Smith    schedule 23.07.2014


Jawaban (2)


Seperti yang dikatakan tumpukan pengecualian, panjangnya harus kelipatan 8.

Jadi, panjang 8, 16, 24,... valid untuk byte kunci.

Coba dengan panjang 8 (12345678)

byte key_bytes[] = "12345678".getBytes();

Jika kesalahan masih berlanjut, Anda dapat mengikuti jawaban

Diperbarui

Jika Anda ingin menggunakan URLDecoder, coba gunakan kode ini dalam metode dekripsi Anda,

String decryptd = URLDecoder.decode(value, "UTF-8");
byte[] dec = new Base64().decode(decryptd);
byte[] utf8 = dcipher.doFinal(dec);  
return new String(utf8, "UTF-8");
person Wundwin Born    schedule 17.07.2014
comment
maaf, saya sudah mengedit pertanyaannya, di sumbernya panjangnya 8 karakter - person John Smith; 17.07.2014
comment
@JohnSmith Anda mungkin perlu mengikuti tautan dalam jawaban yang diperbarui. - person Wundwin Born; 17.07.2014
comment
Saya tidak melihat perbedaan apa pun, hanya standar enkripsi dan pengkodean/dekode UTF-8, yang digunakan dalam kode saya - person John Smith; 18.07.2014
comment
@JohnSmith Masalahnya ada pada metode enkripsi Anda jika Anda mengembalikan string encrypted alih-alih return URLEncoder.encode(encrypted, "UTF-8");, semuanya akan baik-baik saja. - person Wundwin Born; 18.07.2014
comment
ya, itu membantu, terima kasih! - person John Smith; 18.07.2014

Anda kehilangan URLDecoder dalam metode dekripsi Anda. Perhatikan bahwa jika string telah dikompromikan dengan cara lain, dan panjangnya bukan lagi kelipatan ukuran blok, Anda akan menerima pengecualian ini untuk mode operasi ECB dan CBC.

person Maarten Bodewes    schedule 17.07.2014
comment
Saya menggunakan encoder Base64 Apache, URL didekodekan di atas, dalam metode lain, jadi nilai input sudah didekodekan - person John Smith; 17.07.2014
comment
Sebaliknya, berfungsi di sistem saya. Periksa apakah string yang diterima adalah string yang dikirim! Perhatikan bahwa inilah alasan Anda harus membuat SSCCE! - person Maarten Bodewes; 17.07.2014
comment
string yang saya terima pada keluaran metode enkripsi sama dengan string yang diberikan sebagai masukan dalam dekripsi - person John Smith; 18.07.2014
comment
Bisakah Anda menunjukkan kepada kami contoh string input yang digunakan untuk dekripsi yang gagal dengan pengecualian ini? Sebaiknya edit menjadi jawaban dan tanggapi bahwa Anda melakukannya di sini. - person Maarten Bodewes; 18.07.2014