Saya perlu menerapkan enkripsi AES 256 bit, tetapi semua contoh yang saya temukan online menggunakan "KeyGenerator" untuk menghasilkan kunci 256 bit, tetapi saya ingin menggunakan passkey saya sendiri. Bagaimana saya bisa membuat kunci saya sendiri? Saya sudah mencoba padding ke 256 bit, tetapi kemudian saya mendapatkan kesalahan dengan mengatakan bahwa kuncinya terlalu panjang. Saya memiliki patch yurisdiksi tidak terbatas yang diinstal, jadi bukan itu masalahnya :)
Yaitu. KeyGenerator terlihat seperti ini ...
// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available
// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
EDIT
Saya benar-benar mengisi kata sandi hingga 256 byte, bukan bit, yang terlalu panjang. Berikut ini adalah beberapa kode yang saya gunakan sekarang sehingga saya memiliki lebih banyak pengalaman dengan ini.
byte[] key = null; // TODO
byte[] input = null; // TODO
byte[] output = null;
SecretKeySpec keySpec = null;
keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
output = cipher.doFinal(input)
Bit "TODO" yang perlu Anda lakukan sendiri :-)
sumber
Jawaban:
Bagikan
password
(achar[]
) dansalt
(abyte[]
—8 byte yang dipilih oleh aSecureRandom
menjadi garam yang baik — yang tidak perlu dirahasiakan) dengan penerima di luar jalur. Kemudian untuk mendapatkan kunci yang baik dari informasi ini: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:
Simpan
ciphertext
daniv
. Pada dekripsi, kodeSecretKey
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: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.
sumber
PBEwith<prf>and<encryption>
algoritma; misalnya, SunJCE tidak menyediakan dan PBE untuk AES. Kedua, memampukan jasypt bukanlah tujuan. Sebuah paket yang dimaksudkan untuk menawarkan keamanan tanpa memerlukan pemahaman tentang prinsip-prinsip yang mendasarinya tampaknya berbahaya.tmp.getEncoded()
sebagai hash. Anda juga harus menyimpansalt
dan iterasi (65536 dalam contoh ini) sehingga Anda dapat menghitung ulang hash ketika seseorang mencoba untuk mengotentikasi. Dalam hal ini, buat garam dengan generator nomor acak kriptografis setiap kali kata sandi diubah.Pertimbangkan untuk menggunakan Modul Crypto Spring Security
Ini memberikan abstraksi sederhana untuk enkripsi dan tampaknya cocok dengan apa yang diperlukan di sini,
Pandangan internal mengungkapkan struktur yang mirip dengan jawaban erickson .
Seperti yang disebutkan dalam pertanyaan, ini juga memerlukan Java Cryptography Extension (JCE) Kebijakan Yurisdiksi Kekuatan Tidak Terbatas (jika tidak Anda akan menemukan
InvalidKeyException: Illegal Key Size
). Ini dapat diunduh untuk Java 6 , Java 7 dan Java 8 .Contoh penggunaan
Dan sampel output,
sumber
NULL_IV_GENERATOR
oleh utilitas Spring tidak aman. Jika aplikasi tidak menyediakan infus, biarkan penyedia memilihnya, dan permintaan setelah inisialisasi.Setelah membaca saran erickson, dan mendapatkan apa yang saya bisa dari beberapa posting lain dan contoh ini di sini , saya telah mencoba untuk memperbarui kode Doug dengan perubahan yang disarankan. Anda bebas mengedit untuk membuatnya lebih baik.
Beberapa catatan: Ini menggunakan kunci enkripsi 128 bit - java tampaknya tidak akan melakukan enkripsi 256 bit out-of-the-box. Menerapkan 256 membutuhkan menginstal beberapa file tambahan ke direktori install java.
Juga, aku bukan orang yang suka bersembunyi. Menyimak.
sumber
printStackTrace()
CipherInputStream
danCipherOutputStream
tidak banyak masalah. Mengocok semua pengecualian di bawah tabel adalah masalah. Fakta bahwa garam tiba-tiba telah menjadi ladang dan bahwa IV diperlukan adalah masalah. Fakta bahwa itu tidak mengikuti konvensi kode Java adalah masalah. Dan fakta bahwa ini hanya berfungsi pada file sementara tidak diminta adalah masalah. Dan bahwa sisa kode pada dasarnya adalah salinan juga tidak membantu. Tetapi mungkin saya akan mengubahnya untuk membuatnya lebih baik, seperti yang disarankan ...Membuat kunci sendiri dari array byte mudah:
Tetapi membuat kunci 256-bit tidak cukup. Jika generator kunci tidak dapat menghasilkan kunci 256-bit untuk Anda, maka
Cipher
kelas mungkin juga tidak mendukung AES 256-bit. Anda mengatakan Anda memiliki patch yurisdiksi yang tidak terbatas yang diinstal, jadi cipher AES-256 harus didukung (tetapi kemudian kunci 256-bit juga harus, jadi ini mungkin masalah konfigurasi).Solusi untuk kurangnya dukungan AES-256 adalah untuk mengambil beberapa implementasi AES-256 yang tersedia secara bebas, dan menggunakannya sebagai penyedia kustom. Ini melibatkan pembuatan
Provider
subclass Anda sendiri dan menggunakannya bersamaCipher.getInstance(String, Provider)
. Tapi ini bisa menjadi proses yang terlibat.sumber
Cipher
, bukan pada penyedia itu sendiri. Anda dapat menggunakan AES-256 di Java 8 dan lebih rendah, tetapi Anda harus menggunakan API berpemilik. Atau runtime yang tidak menimbulkan batasan pada ukuran kunci tentunya.Apa yang telah saya lakukan di masa lalu adalah hash kunci melalui sesuatu seperti SHA256, kemudian ekstrak byte dari hash ke byte kunci [].
Setelah Anda memiliki byte [], Anda dapat melakukannya:
sumber
Cipher aes256 = Cipher.getInstance("AES/OFB/NoPadding"); MessageDigest keyDigest = MessageDigest.getInstance("SHA-256"); byte[] keyHash = keyDigest.digest(secret.getBytes("UTF-8")); SecretKeySpec key = new SecretKeySpec(keyHash, "AES"); aes256.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(initializationVector));
Saya juga melakukan hal yang sama seperti yang disarankan dalam jawaban Anda, tetapi saya masih berakhir dengan java.security.InvalidKeyException ini: Ukuran kunci ilegal Apakah mengunduh file kebijakan JCE wajib?Menambahkan ke pengeditan @ Wufoo, versi berikut menggunakan InputStreams daripada file untuk membuat bekerja dengan berbagai file lebih mudah. Ini juga menyimpan IV dan Garam di awal file, sehingga hanya kata sandi yang perlu dilacak. Karena IV dan Garam tidak perlu dirahasiakan, ini membuat hidup sedikit lebih mudah.
sumber
(Mungkin bermanfaat untuk orang lain dengan persyaratan serupa)
Saya memiliki persyaratan yang sama untuk menggunakan
AES-256-CBC
enkripsi dan dekripsi di Jawa.Untuk mencapai (atau menentukan) enkripsi / dekripsi 256-byte,
Java Cryptography Extension (JCE)
kebijakan harus diatur ke"Unlimited"
Itu dapat diatur dalam
java.security
file di bawah$JAVA_HOME/jre/lib/security
(untuk JDK) atau$JAVA_HOME/lib/security
(untuk JRE)crypto.policy=unlimited
Atau dalam kode as
Java 9 dan versi yang lebih baru mengaktifkannya secara default.
sumber
Pertimbangkan untuk menggunakan Encryptor4j yang saya penulisnya.
Pertama-tama pastikan Anda memiliki file Kebijakan Yurisdiksi Kekuatan Tidak Terbatas yang diinstal sebelum melanjutkan sehingga Anda dapat menggunakan kunci AES 256-bit.
Kemudian lakukan hal berikut:
Anda sekarang dapat menggunakan enkripsi untuk mengenkripsi pesan Anda. Anda juga dapat melakukan enkripsi streaming jika mau. Secara otomatis menghasilkan dan menambahkan IV aman untuk kenyamanan Anda.
Jika ini adalah file yang ingin Anda kompres, lihat jawaban ini. Enkripsi file besar dengan AES menggunakan JAVA untuk pendekatan yang lebih sederhana.
sumber
Gunakan kelas ini untuk enkripsi. Berhasil.
Dan ini adalah ivBytes dan kunci acak;
sumber