Ini adalah halaman pertama yang muncul melalui Google dan kerentanan keamanan di semua implementasi membuat saya merasa ngeri, jadi saya memposting ini untuk menambahkan informasi mengenai enkripsi untuk orang lain karena sudah 7 tahun dari posting asli. Saya memegang gelar Magister Teknik Komputer dan menghabiskan banyak waktu belajar dan belajar Kriptografi jadi saya melempar dua sen untuk menjadikan internet tempat yang lebih aman.
Juga, perlu dicatat bahwa banyak implementasi mungkin aman untuk situasi tertentu, tetapi mengapa menggunakan itu dan berpotensi membuat kesalahan? Gunakan alat terkuat yang Anda miliki kecuali Anda memiliki alasan khusus untuk tidak melakukannya. Secara keseluruhan saya sangat menyarankan menggunakan perpustakaan dan tinggal jauh dari rincian seluk beluk jika Anda bisa.
UPDATE 4/5/18: Saya menulis ulang beberapa bagian untuk membuatnya lebih mudah dimengerti dan mengubah perpustakaan yang direkomendasikan dari Jasypt ke perpustakaan baru Google Tink , saya akan merekomendasikan sepenuhnya menghapus Jasypt dari pengaturan yang ada.
Kata pengantar
Saya akan menguraikan dasar-dasar kriptografi simetris aman di bawah ini dan menunjukkan kesalahan umum yang saya lihat online ketika orang mengimplementasikan kripto sendiri dengan perpustakaan Java standar. Jika Anda ingin melewatkan semua detail yang berlarian ke perpustakaan baru Google, impor Tink itu ke proyek Anda dan gunakan mode AES-GCM untuk semua enkripsi Anda dan Anda akan aman.
Sekarang jika Anda ingin mempelajari rincian seluk beluk tentang cara mengenkripsi di java baca terus :)
Blokir Cipher
Hal pertama yang pertama Anda perlu memilih kunci simetris Block Cipher. Block Cipher adalah fungsi / program komputer yang digunakan untuk membuat Pseudo-Randomness. Pseudo-Randomness adalah keacakan palsu yang tidak ada komputer selain dari Komputer Quantum yang dapat membedakan antara itu dan keacakan nyata. Block Cipher adalah seperti blok penyusun untuk kriptografi, dan ketika digunakan dengan mode atau skema berbeda kita dapat membuat enkripsi.
Sekarang mengenai Block Cipher Algorithms yang tersedia hari ini, Pastikan untuk TIDAK PERNAH , saya ulangi TIDAK PERNAH menggunakan DES , saya bahkan akan mengatakan TIDAK PERNAH menggunakan 3DES . Satu-satunya Block Cipher yang bahkan rilis NSA Snowden mampu memverifikasi benar-benar sedekat mungkin dengan Pseudo-Random adalah AES 256 . Ada juga AES 128; perbedaannya adalah AES 256 bekerja di blok 256-bit, sedangkan AES 128 bekerja di 128 blok. Secara keseluruhan, AES 128 dianggap aman meskipun beberapa kelemahan telah ditemukan, tetapi 256 sekuat yang didapat.
Fakta asyiknya DES dihancurkan oleh NSA ketika awalnya didirikan dan benar-benar dirahasiakan selama beberapa tahun. Meskipun beberapa orang masih mengklaim 3DES aman, ada beberapa makalah penelitian yang telah menemukan dan menganalisis kelemahan dalam 3DES .
Mode Enkripsi
Enkripsi dibuat ketika Anda mengambil cipher blok dan menggunakan skema tertentu sehingga keacakan dikombinasikan dengan kunci untuk menciptakan sesuatu yang dapat dibalik selama Anda tahu kuncinya. Ini disebut sebagai Mode Enkripsi.
Berikut adalah contoh mode enkripsi dan mode paling sederhana yang dikenal sebagai ECB supaya Anda dapat memahami apa yang sedang terjadi secara visual:
Mode enkripsi yang paling sering Anda lihat online adalah sebagai berikut:
RKPT ECB, CBC, GCM
Ada mode lain di luar yang terdaftar dan peneliti selalu bekerja menuju mode baru untuk memperbaiki masalah yang ada.
Sekarang mari kita beralih ke implementasi dan apa yang aman. JANGAN PERNAH menggunakan ECB ini buruk menyembunyikan data berulang seperti yang ditunjukkan oleh penguin Linux yang terkenal .
Saat menerapkan di Java, perhatikan bahwa jika Anda menggunakan kode berikut, mode ECB diatur secara default:
Cipher cipher = Cipher.getInstance("AES");
... BAHAYA INI ADALAH KERENTANAN! dan sayangnya, ini terlihat di seluruh StackOverflow dan online dalam tutorial dan contoh.
Nonces dan infus
Menanggapi masalah yang ditemukan dengan mode ECB, kata benda juga dikenal sebagai infus dibuat. Idenya adalah bahwa kita menghasilkan variabel acak baru dan melampirkannya ke setiap enkripsi sehingga ketika Anda mengenkripsi dua pesan yang sama mereka keluar berbeda. Keindahan di balik ini adalah infus atau nonce adalah pengetahuan publik. Itu berarti penyerang dapat memiliki akses ke ini tetapi selama mereka tidak memiliki kunci Anda, mereka tidak dapat melakukan apa pun dengan pengetahuan itu.
Masalah umum yang akan saya lihat adalah bahwa orang akan menetapkan IV sebagai nilai statis seperti dalam nilai tetap yang sama dalam kode mereka. dan di sini adalah jebakan ke infus saat Anda mengulanginya Anda benar-benar kompromi seluruh keamanan enkripsi Anda.
Menghasilkan A Random IV
SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
Catatan: SHA1 rusak tetapi saya tidak bisa menemukan cara menerapkan SHA256 ke dalam use case ini dengan benar, jadi jika ada yang ingin mengambil celah ini dan memperbaruinya akan luar biasa! Juga serangan SHA1 masih tidak konvensional karena bisa memakan waktu beberapa tahun pada sekelompok besar untuk memecahkan. Lihat detailnya di sini.
Implementasi RKPT
Padding tidak diperlukan untuk mode CTR.
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
Implementasi KBK
Jika Anda memilih untuk menerapkan Mode CBC melakukannya dengan PKCS7Padding sebagai berikut:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
Kerentanan CBC dan CTR dan Mengapa Anda Harus Menggunakan GCM
Meskipun beberapa mode lain seperti CBC dan CTR aman, mereka mengalami masalah di mana penyerang dapat membalik data yang dienkripsi, mengubah nilainya ketika didekripsi. Jadi katakanlah Anda mengenkripsi pesan bank imajiner "Jual 100", pesan terenkripsi Anda terlihat seperti ini "eu23ng" penyerang berubah sedikit menjadi "eu53ng" dan tiba-tiba ketika mendekripsi pesan Anda, itu berbunyi "Jual 900".
Untuk menghindari hal ini, sebagian besar internet menggunakan GCM, dan setiap kali Anda melihat HTTPS, mereka mungkin menggunakan GCM. GCM menandatangani pesan terenkripsi dengan hash dan memeriksa untuk memverifikasi bahwa pesan belum diubah menggunakan tanda tangan ini.
Saya akan menghindari penerapan GCM karena kerumitannya. Anda lebih baik menggunakan perpustakaan baru Googles Tink karena di sini lagi jika Anda secara tidak sengaja mengulangi IV Anda kompromi kunci dalam kasus dengan GCM, yang merupakan kelemahan keamanan utama. Peneliti baru sedang bekerja menuju mode enkripsi tahan berulang IV di mana bahkan jika Anda mengulangi IV kuncinya tidak dalam bahaya tetapi ini belum datang arus utama.
Sekarang jika Anda ingin mengimplementasikan GCM, berikut adalah tautan ke implementasi GCM yang bagus . Namun, saya tidak dapat memastikan keamanan atau jika itu diterapkan dengan benar tetapi mendapat dasar. Perhatikan juga dengan GCM tidak ada padding.
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
Kunci vs. Kata Sandi
Catatan lain yang sangat penting, adalah kriptografi Kunci dan Kata Sandi bukanlah hal yang sama. Kunci dalam kriptografi perlu memiliki sejumlah entropi dan keacakan agar dianggap aman. Inilah sebabnya mengapa Anda perlu memastikan untuk menggunakan perpustakaan kriptografi yang tepat untuk menghasilkan kunci untuk Anda.
Jadi Anda benar-benar memiliki dua implementasi yang dapat Anda lakukan di sini, yang pertama adalah menggunakan kode yang ditemukan di utas StackOverflow ini untuk Pembuatan Kunci Acak . Solusi ini menggunakan penghasil angka acak yang aman untuk membuat kunci dari awal yang dapat Anda gunakan.
Opsi lain yang kurang aman adalah menggunakan input pengguna seperti kata sandi. Masalah yang kita bahas adalah bahwa kata sandi tidak memiliki cukup entropi, jadi kita harus menggunakan PBKDF2 , sebuah algoritma yang mengambil kata sandi dan memperkuatnya. Berikut ini adalah implementasi StackOverflow yang saya sukai . Namun pustaka Google Tink memiliki semua ini bawaan dan Anda harus memanfaatkannya.
Pengembang Android
Satu poin penting untuk ditunjukkan di sini adalah tahu bahwa kode android Anda adalah rekayasa balik dan kebanyakan kasus kebanyakan kode java juga. Itu berarti jika Anda menyimpan kata sandi dalam teks biasa dalam kode Anda. Seorang hacker dapat dengan mudah mengambilnya. Biasanya, untuk jenis enkripsi ini, Anda ingin menggunakan Asymmetric Cryptography dan sebagainya. Ini di luar cakupan posting ini jadi saya akan menghindari menyelam ke dalamnya.
Sebuah bacaan yang menarik dari 2013 : hai bahwa 88% dari implementasi Crypto di Android yang dilakukan tidak benar.
Pikiran terakhir
Sekali lagi saya akan menyarankan menghindari menerapkan perpustakaan java untuk crypto secara langsung dan menggunakan Google Tink , ini akan menghemat sakit kepala karena mereka telah benar-benar melakukan pekerjaan yang baik dalam mengimplementasikan semua algoritma dengan benar. Dan bahkan kemudian pastikan Anda memeriksa masalah yang muncul di Tink github, kerentanan muncul di sana-sini.
Jika Anda memiliki pertanyaan atau umpan balik, jangan ragu untuk berkomentar! Keamanan selalu berubah dan Anda harus melakukan yang terbaik untuk mengatasinya :)