Prinsip -prinsip implementasi dan ide -ide Java yang menerapkan enkripsi mode SSH dibagikan kepada Anda.
1. Prinsip Enkripsi SSH
SSH pertama -tama memberi tahu kata sandi enkripsi asimetris server melalui enkripsi asimetris, dan kemudian menggunakan kata sandi enkripsi yang sudah diketahui oleh kedua belah pihak untuk enkripsi dan dekripsi, lihat gambar di bawah ini:
Penjelasan: Mengapa kita perlu menggunakan enkripsi asimetris dan enkripsi simetris di SSH? Apa gunanya itu? Apakah aman atau tidak? Lalu kami menggunakan enkripsi simetris, mengapa kami menggunakan enkripsi asimetris di awal? Di sisi lain, karena enkripsi asimetris digunakan, mengapa enkripsi simetris harus digunakan?
Enkripsi asimetris adalah untuk lulus kata sandi acak 256-bit yang dihasilkan oleh klien ke server. Kemudian, selama proses pengiriman, kunci publik digunakan untuk enkripsi, sehingga kata sandi terenkripsi 256-bit ini sulit untuk retak di jaringan.
Enkripsi simetris, karena sering menggunakan enkripsi asimetris adalah pemborosan kinerja, SSH menggunakan kata sandi panjang 256-bit sebagai kata sandi yang dienkripsi saat menyampaikan nama pengguna dan kata sandi berikutnya. Saya percaya semua orang tahu kesulitan retak, dan ada 0-9 perubahan di setiap bit.
Apakah ini aman? Saya pikir itu masih sangat bagus, dan mudah dimengerti saat digunakan.
2. Prinsip Enkripsi SSH saya
①, skenario penggunaan
Proyek yang saya kembangkan adalah perdagangan berjangka massal, yang terutama melayani pertukaran, yang menciptakan permintaan yang kita butuhkan untuk mengontrol siklus pertukaran menggunakan perangkat lunak kita. Dengan kata lain, proyek kami memiliki pintu belakang untuk mengontrol siklus proyek. Jika pertukaran menggunakan siklus perangkat lunak, jika tidak memperbarui dan kode proyek digunakan di server orang lain, akan sulit bagi kita untuk mengendalikannya. Namun, dengan pintu belakang ini, perangkat lunak akan dihentikan secara otomatis setelah berakhir, jadi kami tidak khawatir pertukaran tidak akan memberi kami uang.
②, metode penggunaan
Kode proyek yang kami berikan transaksi berisi backdoor, yang mengirimkan permintaan ke layanan web melalui klien layanan web.
Setelah menerima permintaan, layanan web mengembalikan informasi yang diperlukan oleh klien.
Dalam proses di atas, metode permintaan enkripsi SSH akan dihasilkan. Tolong izinkan saya menggunakan sosok canggung untuk mewakilinya.
3. Implementasi SSH saya
Karena Anda ingin menggunakan WebService, Anda perlu membuat layanan layanan web dan klien layanan web. Saya tidak ingin mengatakan terlalu banyak tentang ini untuk saat ini, ada banyak cara, jadi saya tidak akan menyesatkan semua orang di sini. Saya melakukannya melalui Eclipse, dan saya dapat merujuk pada komunikasi antara layanan web.
Selanjutnya, saya akan memperkenalkan kode, tetapi mengingat masalah panjang, saya tidak akan memposting beberapa kode yang tidak perlu. Kuncinya adalah menjelaskan prinsip ini dengan jelas.
①, layanan
Exchangeservice.java
byte publik [] permintaan (string param, string resultType) {logger.info ("Parameter permintaan:" + param); // mengembalikan objek keyresult keyResult = keyresult baru (); coba {// dapatkan kunci publik terlebih dahulu if (resultType.equals (public_key_result_type)) {peta <string, object> keymap = rsacoder.initkey (); // menghasilkan kunci publik dan pribadi privateKey = rsacoder.getprivatekey (keymap); keyresult.setKey (rsacoder.getpublickey (keymap)); logger.info ("String kunci publik:" + keyResult.getKey ()); Logger.info ("String Kunci Pribadi:" + PrivateKey); } lain if (resultType.equals (echoStr_result_type)) {// Atur informasi kata sandi dari byte klien [] PARAMBYTE = base64decoder baru (). DecodeBuffer (param); echoStr = string baru (rsacoder.decryptbyprivatekey (Paramatte, privateKey)); } else {// Dapatkan informasi izin yang sesuai dengan pertukaran melalui database. // Konversi terlebih dahulu permintaan ke array byte, lalu mendekripsi, dan akhirnya mengonversinya ke string ExchangeInfo info = ExchangeInfo.dao.getInfobyname (string baru (cryptutil.decrypt (base64decoder (). Decodebuffer (param), echostr.getbytes ()))). Hasil string = ""; // Dapatkan izin yang diaktifkan sistem jika (resultType. // Konversi ke hari int hari = (int) (waktu / (60 * 60 * 24)); // Jumlah hari yang masih dapat digunakan jika (bekas - hari> 0) {// Anda dapat menggunakan hasil = "1"; } else {// Anda tidak dapat menggunakan hasil = "0"; }} keyResult.setresult (cryptutil.encrypt (result.getbytes (), echostr.getbytes ())); } return jsonutil.objecttobyte (keyresult); } catch (Exception e) {Logger.Error ("Kesalahan WebService !!!"); logger.error (e.getMessage (), e); } return null;}Izinkan saya menjelaskannya:
Konten dalam pernyataan penilaian pertama adalah untuk menghasilkan kunci publik dan pribadi dan mengembalikan kunci publik.
Konten dalam pernyataan penilaian kedua adalah menyimpan string acak yang dikirim oleh klien. Langkah ini sangat kritis. String acak pertama kali dienkripsi dengan kunci publik, yang sangat meningkatkan kedalaman enkripsi.
Konten dalam pernyataan penilaian ketiga adalah mengenkripsi izin klien melalui string acak.
②, klien
Exchangeutil.java
public static boolean canrunforexchange (string resultType) {int i = 1; Hasil boolean = false; while (true) {coba {// webservice call class ExchangeserviceProxy proxy = ExchangeServiceProxy () baru; Base64Encoder encoder = base64Encoder baru (); // Step1. Dapatkan kunci publik yang dihasilkan oleh layanan keyresult keyResult = jsonutil.bytetoObject (proxy.Request (null, public_key_result_type), keyresult.class); // Step2. Menghasilkan string acak dan mengirimkannya ke string webserivce echoStr = strutil.geteChoStrbylength (10); byte [] echobyteparam = rsacoder.encryptbypublickey (echostr.getbytes (), keyresult.getKey ()); proxy.request (encoder.encode (echobyteparam), echostr_result_type); // Langkah3. Mengenkripsi informasi permintaan klien dan mengirimkannya ke WebService // pertama -tama enkripsi sebagai array byte, dan kemudian mengubahnya menjadi string byte [] hasil = proxy.request (encoder.encode (cryptutil.etrypt (constants.client_type.getbytes (), echostr.getbytes ())))))) keyResult = jsonutil.bytetoObject (hasil, keyresult.class); // Langkah4. Kembalikan pesan melalui kata sandi Dekripsi Server String Response = String baru (cryptutil.decrypt (keyResult.getResult (), echostr.getbytes ())); if (response.equals ("1")) {result = true; } merusak; } catch (Exception e) {logger.debug ("th" + i + "Time Loading WebService Gagal"); i ++; logger.error (e.getMessage (), e); if (i> = 10) {break; }}} return hasil;}Penjelasan singkat:
Loop terutama untuk mencegah layanan dari mengirim permintaan terus menerus ketika jaringan terputus, dan hingga 10 kali sudah cukup.
Ada empat langkah utama, dan apa yang ingin saya jelaskan dalam komentar tidak apa -apa.
③, enkripsi dan dekripsi kelas publik bersama
Cryptutil.java
Paket com.honzh.socket.util; import javax.crypto.cipher; import javax.crypto.secretkey; import javax.crypto.secretkeyfactory; import javax.crypto.spec.deskeyspec; impor javax.crypto.spec.spec.spec @Title: Encrypt * @description: Encrypt * @param Data * @param Key * @return * @throws Exception */ public static byte [] encrypt (byte [] data, byte [] key) melempar pengecualian {key = get8 (key); Cipher cipher = cipher.getInstance ("des/cbc/pkcs5padding"); Deskeyspec deskeyspec = deskeyspec baru (kunci); Secretkey KeyFactory = SecretkeyFactory.getInstance ("des"); Secretkey Secretkey = KeyFactory.GenerateSecret (Deskeyspec); Ivparameterspec iv = ivparameterspec baru (kunci); cipher.init (cipher.encrypt_mode, Secretkey, iv); return cipher.dofinal (data); } / ** * @title: decrypt * @description: decrypt * @param data * @param Key * @return * @throws Exception * / public static byte [] decrypt (byte [] data, byte [] Key) melempar pengecualian {key = get8 (key); Cipher cipher = cipher.getInstance ("des/cbc/pkcs5padding"); Deskeyspec deskeyspec = deskeyspec baru (kunci); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance ("des"); Secretkey Secretkey = KeyFactory.GenerateSecret (Deskeyspec); Ivparameterspec iv = ivparameterspec baru (kunci); cipher.init (cipher.decrypt_mode, Secretkey, iv); return cipher.dofinal (data); } private static byte [] get8 (byte [] key) {byte [] key1 = byte baru [8]; untuk (int i = 0; i <8; i ++) {key1 [i] = key [i]; } return key1; } public static String tohexString (byte [] data) {string s = ""; untuk (int i = 0; i <data.length; i ++) {s+= integer.toHexString (data [i] & 0xff)+"-"; } return s; }} Secara umum, enkripsi SHA dan MD5 sudah cukup untuk kita gunakan!
Adapun kategori tambahan lainnya, saya tidak akan memperkenalkannya. Ada banyak sumber daya di internet, dan saya harap semua orang dapat belajar dalam kombinasi.