Editor teks multi-pengguna yang sederhana dengan enkripsi ujung ke ujung

Pendahuluan


Hari ini, keamanan informasi adalah salah satu prioritas industri TI, terutama mengingat bahwa untuk mendengarkan lalu lintas di zaman kita, Anda praktis tidak memerlukan pengetahuan khusus - di Internet ada cukup banyak perangkat lunak dan manual terperinci.

Oleh karena itu, saya mengatur dan menyelesaikan masalah penulisan layanan untuk bertukar file, yang dirancang sedemikian rupa sehingga akan terlindungi dari serangan "orang di tengah" - file yang dikirimkan melalui layanan tidak boleh pergi dari kartu jaringan perangkat akhir dalam bentuk yang tidak dienkripsi, dan dekripsi, oleh karena itu, harus dilakukan pada mesin penerima akhir.

Pemilihan alat


Untuk menulis sisi server aplikasi, saya memilih bahasa pemrograman Java dikombinasikan dengan kerangka pengembangan web Wicket. Ini bukan satu-satunya toolkit yang memungkinkan untuk mengimplementasikan tugas-tugas, tetapi tumpukan ini cukup untuk menyelesaikannya, dan Wicket, antara lain, menyediakan antarmuka yang sangat nyaman untuk bekerja dengan komponen halaman web. Frontend tidak menyiratkan adanya sesuatu yang rumit di dalamnya - saya tidak mengatur diri saya tugas mengembangkan antarmuka yang indah dan ramah, logika aplikasi adalah prioritas yang lebih tinggi, jadi saya membatasi diri pada bundel HTML / CSS / JS klasik.

Server berjalan pada Ubunty 18.04, dalam wadah Docker - tetapi konfigurasi server akan dibahas lebih rinci di bawah ini - menggunakan wadah servlet Apache Tomcat. Teknologi lain yang diperlukan untuk membangun aplikasi seperti itu, jika perlu, akan disebutkan selama artikel.

Konfigurasi server


Seperti yang telah disebutkan, aplikasi ini terletak di server linux, khususnya, pada Ubunty 18.04. Untuk mengisolasi sistem dari aplikasi lain, serta untuk menyederhanakan penyebaran, diputuskan untuk melakukan proses kemunduran - dengan bantuan DoCker mengalokasikan aplikasi sejumlah CPU dan memori, membuka daftar port, dan menutup sisanya. Saya tidak akan menjelaskan secara terperinci pemasangan dan konfigurasi layanan Docker, tetapi saya harus menyebutkan poin-poin utama.

Diasumsikan bahwa semua perintah dijalankan dengan hak administrator.

Untuk memulai, diperlukan untuk menginstal dan memulai layanan yang sesuai, dengan perintah

# apt install docker-e # systemctl start docker # systemctl enable docker 

Setelah itu, unduh dan jalankan gambar sistem operasi - kami tidak memerlukan apa pun dari wadah saat ini:

 #docker search ubuntu #docker pull ubuntu #docker run -it ubuntu 

Gaya prompt input seharusnya telah berubah - sekarang kita berada di wadah dan dapat bekerja tanpa takut dengan lingkungan nyata. Mungkin beberapa paket yang biasa kita gunakan pada mesin sungguhan dalam wadah akan terlewatkan, tetapi prosedur untuk menginstalnya tidak berbeda dengan memasang paket pada mesin sungguhan, jadi saya tidak akan fokus pada hal ini. Lebih lanjut diasumsikan bahwa semua tindakan dilakukan di dalam wadah.

Mengkonfigurasi Wadah Tomcat Servlet


Jadi, saat ini, kami menganggap bahwa kami sedang mengerjakan sistem operasi yang bersih, di mana semuanya secara default. Agar dapat meng-host aplikasi Java di dalamnya, Anda perlu menginstal jdk dan jvm secara langsung di atasnya, dan mengatur variabel lingkungan dengan jalur instalasi. Oleh karena itu, di sini saya hanya akan memberikan perintah kunci, lebih terinci proses menginstal Java di Linux dapat dipertimbangkan di jaringan.

Untuk menginstal JDK dan JRE, dan kemudian menyetel variabel lingkungan JAVA_HOME, Anda harus memasukkan perintah ini sesuai:

 #apt install openjdk-8-jdk #apt install openjdk-8-jre #export JAVA_HOME β€œ____JAVA” 

Kemudian Anda dapat langsung menginstal Tomcat.

Hal utama yang harus diperhatikan - pemberian hak manajer dan administrator - secara default, Anda tidak dapat mengelola aplikasi dari jarak jauh, bukan pada mesin lokal. Jika tidak, semuanya standar - mengunduh dan menginstal paket dan memulai layanan.

Menulis program


Program, seperti yang disebutkan di atas, akan terdiri dari bagian server dan klien. Kami akan mempertimbangkan secara singkat sisi klien, file Editor dan fungsi enkripsi adalah yang paling diminati.

Namun, hal pertama yang pertama.

Mari kita mulai dengan sisi klien.

Seperti yang direncanakan, itu harus memberikan akses ke daftar file yang disimpan di server. Karena solusinya seharusnya murah, saya mentransfer daftar file dalam bentuk teks untuk kotak teks tidak aktif, dan melampirkan formulir di bagian bawah untuk memilih nama file untuk dibuka.

gambar
Fig. 1 - Antarmuka Penyimpanan File

Ketika Anda memasukkan nama file di baris input, file akan terbuka di jendela lain - di editor. Kode Java untuk halaman yang mencantumkan file:

 File directory = new File(wayToDirs); String files = new String(); directory.mkdirs(); for (File i : directory.listFiles()) files+=i.getName()+"\n"; TextArea listOfFiles = new TextArea("files", Model.of("")); listOfFiles.setEnabled(false); listOfFiles.setDefaultModelObject(files); add(listOfFiles); 

HTML yang sesuai bahkan lebih sepele:

 <textarea wicket:id = "files" class="files" id = "files" /> <form wicket:id="selector" > <textarea wicket:id="name" class="input"/> <button wicket:id="opener" class="input" style="width: 10%"></button> </form> 

Seperti yang telah disebutkan di atas, halaman dengan editor dan enkripsi secara langsung mewakili minat. Di sana, pembukaan, modifikasi, enkripsi, dan dekripsi file yang diperlukan, serta penyimpanannya, berlangsung.

gambar
Fig. 2 - antarmuka editor

Mari kita mulai dengan sisi server - lebih mudah dimengerti. Dari sudut pandang server, aplikasi harus mengklik tombol untuk menerima teks dari jendela input teks, menerima nama file dari baris yang sesuai dan menyimpan dokumen yang dihasilkan. Sebenarnya, inilah yang terjadi dalam daftar di bawah ini.

 TextField wayToSaveFile = new TextField("wayToSaveFile", Model.of("")); Button saveButton = new Button("save") { @Override public void onSubmit() { super.onSubmit(); File file = new File(DirectoryInterface.wayToDirs+"/" + wayToSaveFile.getInput()); try { FileWriter fw = new FileWriter(file); fw.write(textArea.getDefaultModelObject().toString()); fw.close(); } catch (Exception e) { System.out.println(e.getMessage()); debud.setDefaultModelObject(e.getMessage()); } } }; 
Tetapi pada saat menyimpan, file sudah dienkripsi. Untuk melakukan ini, tombol "Enkripsi" dan "Dekripsi" diimplementasikan di bagian klien, yang digunakan untuk enkripsi dan dekripsi. Enkripsi berlangsung sesuai dengan algoritma Vigenere, saya akan mengatakan sedikit lebih banyak tentang hal itu secara terpisah, tetapi ditunjukkan dalam fungsinya.

Dengan demikian, kode klien terlihat seperti ini:

 <script> function encryptFun(){ let outputString = ""; let inputString = document.getElementById("text").value; let password = document.getElementById("passwordTextField").value; for (let i = 0; i<inputString.toString().length-1; i++) outputString+=(String.fromCharCode((inputString.toString().charCodeAt(i)+256-password.toString().charCodeAt(i%password.toString().length))%256)); document.getElementById("text").value = outputString; return outputString; }; function decryptFun(){ let outputString = ""; let inputString = document.getElementById("text").value; let password = document.getElementById("passwordTextField").value; for (let i = 0; i<inputString.toString().length-1; i++) outputString+=(String.fromCharCode((inputString.toString().charCodeAt(i)+256+password.toString().charCodeAt(i%password.toString().length))%256)); document.getElementById("text").value = outputString; return outputString; }; </script> … <!β€”  -οƒ  <input wicket:id="wayToSaveFile"class="input"> <button wicket:id = "save" class="input">Save</button> <input id = "passwordTextField" class="input"> <button id = "encrypt" onclick="encryptFun()" class="input"></button> <button id = "decrypt" onclick="decryptFun()" class="input"></button> 

Jadi, setelah menekan tombol enkripsi, teks di bidang input diganti dengan teks yang dikembalikan oleh fungsi enkripsi - dan sebaliknya.

Versi aplikasi saat ini tidak secara otomatis menentukan apakah teks dienkripsi, sehingga teks yang tidak terhubung dianggap dienkripsi.

Algoritma enkripsi


Saya telah memilih algoritma enkripsi Vigenere - yang merupakan variasi dari cipher Caesar dengan perubahan variabel berdasarkan kata kunci. Kode sumber input dan kunci panjang sewenang-wenang. Kemudian anggota ke-i dari teks sumber digeser dengan nomor urut dalam alfabet simbol kata sandi ke-j, di mana j = i% (panjang kata sandi). Algoritme bukan yang paling optimal atau tahan terhadap analisis, namun, dengan panjang kata sandi yang memadai, ia menyediakan beberapa keandalan.

Menurut bahan dari literatur tentang kriptanalisis, cipher Vigenere β€œmengaburkan” karakteristik frekuensi kemunculan karakter dalam teks, tetapi beberapa fitur dari penampilan karakter dalam teks tetap ada. Kerugian utama dari cipher Vigenere adalah kuncinya diulang. Oleh karena itu, pembacaan sandi sederhana dari sebuah sandi dapat dibangun dalam dua tahap:

  1. Pencarian panjang kunci. Anda dapat menganalisis distribusi frekuensi dalam teks terenkripsi dengan penipisan berbeda. Yaitu, ambil teks yang menyertakan setiap huruf ke-2 dari ciphertext, lalu setiap ke-3, dll. Begitu distribusi frekuensi huruf-huruf tersebut sangat berbeda dari seragam (misalnya, dengan entropi), kita dapat berbicara tentang panjang kunci yang ditemukan.
  2. Kriptanalisis. Satu set l cipher Caesar (di mana l adalah panjang kunci ditemukan), yang secara individual mudah retak.

Tes Friedman dan Kassiski dapat membantu menentukan panjang kunci.

Diskusi yang lebih terperinci tentang retasan Vizhener sekali lagi berada di luar cakupan artikel ini.

Kesimpulan


Dalam kerangka artikel ini, sebuah algoritma ditulis untuk menulis aplikasi yang menyediakan penyimpanan dan pengiriman file teks yang aman melalui jaringan yang memerlukan akses bersama.

Beberapa keputusan yang disuarakan di atas kontroversial atau tidak optimal, tetapi logika dasar dan hal-hal mendasar ditunjukkan.
github.com/Toxa-p07a1330/encriptedStorage

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


All Articles