Kriptografi di Jawa. Cipher kelas

Halo, Habr! Saya mempersembahkan kepada Anda terjemahan artikel kedua "Java Cipher" oleh Jakob Jenkov dari serangkaian artikel untuk pemula yang ingin mempelajari dasar-dasar kriptografi di Jawa.


Daftar isi:


  1. Kriptografi
  2. Sandi
  3. Pesan pesan
  4. Mac
  5. Tanda tangan
  6. Keypair
  7. Keygenerator
  8. KeyPairGenerator
  9. Keystore
  10. Keytool
  11. Sertifikat
  12. Pabrik Sertifikat
  13. CertPath

Java Cipher (Cipher)


Kelas Java Cipher ( javax.crypto.Cipher ) adalah algoritma enkripsi. Istilah "Cipher" adalah istilah standar untuk algoritma enkripsi dalam dunia kriptografi. Inilah sebabnya mengapa kelas Java disebut Cipher , dan bukan Encryptor / Decryptor atau yang lainnya. Anda dapat menggunakan instance Cipher untuk mengenkripsi dan mendekripsi data dalam Java. Bab ini menjelaskan cara kerja kelas Cipher.


Penciptaan Sandi


Sebelum menggunakan cipher, Anda harus membuat instance dari kelas Cipher dengan memanggil metode getInstance () dengan parameter yang menunjukkan jenis algoritma enkripsi yang ingin Anda gunakan. Berikut adalah contoh membuat instance Java Cipher:


Cipher cipher = Cipher.getInstance("AES"); 

Contoh ini membuat instance Cipher menggunakan algoritma enkripsi AES.


Mode enkripsi


Beberapa algoritma enkripsi dapat bekerja dalam mode yang berbeda. Mode enkripsi menentukan detail bagaimana data akan dienkripsi. Jadi, mode enkripsi secara parsial mempengaruhi algoritma enkripsi. Mode enkripsi kadang-kadang dapat digunakan dalam beberapa algoritma enkripsi yang berbeda - sebagai metode yang ditambahkan ke algoritma enkripsi utama. Itu sebabnya mode dianggap terpisah dari algoritma enkripsi itu sendiri, tetapi lebih sebagai "tambahan" untuk algoritma enkripsi. Berikut adalah beberapa mode enkripsi yang paling dikenal:


  • EBC - Codebook Elektronik ( Mode Codebook Elektronik)
  • CBC - Cipher Block Chaining
  • CFB - Umpan Balik Cipher ( Mode Umpan Balik Cipher)
  • OFB - Umpan Balik Output
  • RKT - Penghitung (Counter Mode )

Saat membuat instance cipher, Anda dapat menambahkan modenya ke nama algoritma enkripsi. Untuk membuat instance AES Cipher menggunakan mode blok kopling - Cipher Block Chaining (CBC), Anda bisa melakukan ini:


 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

Karena mode kopling dari blok enkripsi juga memerlukan "skema padding", skema padding ( PKCS5Padding ) ditambahkan ke akhir string nama algoritma enkripsi.
Penting untuk diketahui bahwa tidak semua algoritma dan mode enkripsi didukung secara default oleh penyedia enkripsi SDK Java. Untuk membuat instance cipher yang Anda butuhkan dengan mode yang diperlukan dan pola pengisian, Anda mungkin perlu menginstal penyedia pihak ketiga, seperti Bouncy Castle.


Inisialisasi sandi


Sebelum menggunakan instance Cipher, harus diinisialisasi. Cipher diinisialisasi dengan memanggil metode init () -nya. Metode init () mengambil dua parameter:


  • Mode
  • Kunci

Contoh menginisialisasi instance Cipher dalam mode enkripsi:


 Key key = ... // /    cipher.init(Cipher.ENCRYPT_MODE, key); 

Dan berikut adalah contoh menginisialisasi instance Cipher yang sudah dalam mode dekripsi:


 Key key = ... ///    cipher.init(Cipher.DECRYPT_MODE, key); 

Enkripsi dan Dekripsi Data


Untuk mengenkripsi atau mendekripsi data menggunakan instance Cipher, salah satu dari dua metode ini disebut:


  • update()
  • doFinal()

Ada beberapa versi pembaruan () dan metode doFinal () yang diganti menggunakan parameter yang berbeda. Pertimbangkan yang paling umum digunakan di sini. Jika Anda perlu mengenkripsi atau mendekripsi satu blok data, cukup panggil doFinal () dengan data untuk mengenkripsi atau mendekripsi. Contoh:


 byte[] plainText = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); byte[] cipherText = cipher.doFinal(plainText); 

Bahkan, kode tersebut terlihat kurang lebih sama dalam hal dekripsi data. Ingat saja bahwa instance Cipher harus diinisialisasi dalam mode dekripsi. Berikut ini dekripsi dari satu blok ciphertext:


 byte[] plainText = cipher.doFinal(cipherText); 

Jika Anda perlu mengenkripsi atau mendekripsi file besar yang dibagi menjadi beberapa blok, perbarui () dipanggil satu kali untuk setiap blok data dan diakhiri dengan panggilan ke metode doFinal () dengan blok data terakhir. Berikut ini contoh mengenkripsi beberapa blok data:


 byte[] data1 = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); byte[] data2 = "zyxwvutsrqponmlkjihgfedcba".getBytes("UTF-8"); byte[] data3 = "01234567890123456789012345".getBytes("UTF-8"); byte[] cipherText1 = cipher.update(data1); byte[] cipherText2 = cipher.update(data2); byte[] cipherText3 = cipher.doFinal(data3); 

Alasan mengapa panggilan doFinal () diperlukan untuk blok data terakhir adalah karena beberapa algoritma enkripsi perlu melengkapi data agar sesuai dengan ukuran blok cipher tertentu (misalnya, batas 8-byte). Tidak perlu menambah data terenkripsi antara. Oleh karena itu, metode pembaruan () dipanggil untuk blok data perantara dan panggilan doFinal () untuk blok data terakhir dipanggil.
Saat mendekripsi beberapa blok data, Anda juga memanggil metode pembaruan () untuk blok data perantara dan metode doFinal () untuk blok terakhir. Contoh dekripsi beberapa blok data:


 byte[] plainText1 = cipher.update(cipherText1); byte[] plainText2 = cipher.update(cipherText2); byte[] plainText3 = cipher.doFinal(cipherText3); 

Sekali lagi, instance cipher harus diinisialisasi dalam mode dekripsi agar contoh ini berfungsi.


Enkripsi / Dekripsi bagian byte array


Metode enkripsi dan dekripsi kelas Cipher dapat mengenkripsi atau mendekripsi beberapa data yang disimpan dalam array byte. Metode pembaruan () dan / atau doFinal () harus melewati offset dan panjang.


 int offset = 10; int length = 24; byte[] cipherText = cipher.doFinal(data, offset, length); 

Dalam contoh ini, byte dari indeks 10 dan maju 24 byte akan dienkripsi (atau didekripsi, tergantung pada inisialisasi cipher).


Enkripsi / Dekripsi ke array byte yang ada


Semua contoh enkripsi dan dekripsi dalam bab ini mengembalikan data terenkripsi atau dekripsi dalam array byte baru. Namun, juga memungkinkan untuk mengenkripsi atau mendekripsi data ke dalam byte array yang ada. Ini berguna untuk mengurangi jumlah array byte yang dibuat. Untuk melakukan ini, kirimkan array byte target sebagai parameter ke metode pembaruan () dan / atau doFinal () .


 int offset = 10; int length = 24; byte[] dest = new byte[1024]; cipher.doFinal(data, offset, length, dest); 

Dalam contoh ini, data dienkripsi dari 10 indeks 24 byte ke depan ke array byte byte dengan offset 0. Jika Anda ingin mengatur offset yang berbeda untuk array byte byte, ada versi pembaruan () dan doFinal () yang menerima parameter offset tambahan. Contoh memanggil metode doFinal () dengan offset di array dest:


 int offset = 10; int length = 24; byte[] dest = new byte[1024]; int destOffset = 12 cipher.doFinal(data, offset, length, dest, destOffset); 

Menggunakan kembali instance cipher


Menginisialisasi instance Cipher adalah operasi yang mahal dan menggunakan kembali instance Cipher adalah ide yang bagus. Untungnya, kelas Cipher telah dirancang dengan dapat digunakan kembali. Ketika Anda memanggil metode doFinal () pada instance Cipher, ia kembali ke kondisi semula setelah inisialisasi. Cipher instance kemudian dapat digunakan untuk mengenkripsi atau mendekripsi lebih banyak data.


Contoh menggunakan kembali contoh Java Cipher:


 Cipher cipher = Cipher.getInstance("AES"); Key key = ... ///    cipher.init(Cipher.ENCRYPT_MODE, key); byte[] data1 = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); byte[] data2 = "zyxwvutsrqponmlkjihgfedcba".getBytes("UTF-8"); byte[] cipherText1 = cipher.update(data1); byte[] cipherText2 = cipher.doFinal(data2); byte[] data3 = "01234567890123456789012345".getBytes("UTF-8"); byte[] cipherText3 = cipher.doFinal(data3); 

Pertama, instance Cipher dibuat dan diinisialisasi, dan kemudian digunakan untuk mengenkripsi dua blok data yang konsisten. Perhatikan panggilan untuk memperbarui () dan kemudian doFinal () untuk dua blok data ini. Setelah itu, instance Cipher dapat digunakan lagi untuk mengenkripsi data. Ini dilakukan dengan memanggil doFinal () dengan blok data ketiga. Setelah panggilan ini ke doFinal (), Anda dapat mengenkripsi blok data lain dengan contoh Java Cipher yang sama.

Source: https://habr.com/ru/post/id444814/


All Articles