Source Code Algoritma Hill Cipher Menggunakan Kunci Matriks 3x3

Table of Contents

Artikel ini kembali membahas tentang algoritma Hill Cipher. Ada kawan yang meminta untuk buatkan pengembangan baru dari aplikasi hill cipher yang pernah saya tulis sebelumnya, dengan judul Algoritma Hill Cipher untuk Mengatasi 256 Karakter ASCII. Memang di pembahasan sebelumnya, hill cipher yang saya kembangkan selalu menggunakan kunci matriks 2x2. Alasan utamanya, kunci 2x2 relatif mudah dihitung serta dibuatkan source code-nya. Pengembangan baru untuk hill cipher adalah mengubah kunci matriks 2x2 menjadi kunci matriks 3x3. Pengembangan ini bertujuan untuk menambah kompleksitas kriptografi, sehingga keamanan kriptografi meningkat.


Pengembangan ini juga lumayan menantang. Saya galau bukan hanya karena source code-nya yang sulit, melainkan juga karena perhitungan manualnya yang ruwet. Prinsip saya simpel, jika menerapkan algoritma ke coding, maka kuasai dulu hitung manualnya. Coding pun akan lebih mudah.

Tantangan hitung manual pada Hill Cipher 3x3 adalah mencari determinan dan mendapatkan invers multiplikatif. Jika hanya mencari determinan untuk 3x3, tentu masih banyak referensinya. Biasanya menggunakan Metode Sarrus. Tapi tutorial untuk invers multiplikatif? rasanya tidak banyak. Jika hanya sekadar invers saja, ada situs kalkulator invers 3x3 yang siap bantu. Namun setelah saya coba, selalu menghasilkan bilangan pecahan. Invers Multiplikatif yang dimaksudkan adalah invers yang menghasilkan nilai tetap bilangan bulat. Ini yang sulit.

Untuk mengakhiri kegalauan saya, sengaja saya beli kitab suci kriptografi karangan dosen ITB, Dr. Rinaldi Munir. Karya-karya beliau sudah jadi referensi utama sejak zaman kuliah dulu. Melalui buku beliau, akhirnya saya mendapatkan contoh perhitungan manual yang jelas. Ada contoh Hill Cipher untuk kunci 2x2, ada pula untuk kunci 3x3. Contoh hitungan itu saya terapkan pada program yang saya kembangkan. Dan akhirnya, BERHASIL. 

Gambar 1. Antar muka Aplikasi Hill Cipher Kunci Matriks 3x3

Gambar 1 menunjukkan tampilan awal program. Sama persis dengan tampilan Hill Cipher kunci 2x2, hanya saja saya ubah matrik kuncinya menjadi 3x3. Pengguna dapat memilih menu Enkripsi maupun Dekripsi. Program ini sudah mampu menampung karakter sebanyak 256, sesuai jumlah karakter standart ASCII (cek tabel ASCII jika belum tahu). Source code dibawah ini, saya fokuskan pada bagian tersulit pada algoritma hill cipher, yaitu mendapatkan invers multiplikatif. Untuk bagian source code yang lain, pernah saya bagi di artikel hill cipher dengan kunci 2x2. 

public int hitungInvers(int[][] matrix) {

        int determinan, x, y, z;

        x = (matrix[0][0] * (matrix[1][1] * matrix[2][2]
                - matrix[1][2] * matrix[2][1]));
        y = (matrix[0][1] * (matrix[1][0] * matrix[2][2]
                - matrix[1][2] * matrix[2][0]));
        z = (matrix[0][2] * (matrix[1][0] * matrix[2][1]
                - matrix[1][1] * matrix[2][0]));
        determinan = x - y + z;

        System.out.println("================== MENGHITUNG INVERS PADA MATRIKS KUNCI =====================");
        System.out.println("Determinan : " + determinan);
        if (determinan == 0) {
            System.out.println("Matrik tidak memiliki invers");
        } else if (determinan < 0) {
            JOptionPane.showMessageDialog(null, "Kunci Tidak Memenuhi Syarat");
        } else {

            int A = (matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2]);
            int B = -(matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0]);
            int C = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]);
            int D = -(matrix[0][1] * matrix[2][2] - matrix[2][1] * matrix[0][2]);
            int E = (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]);
            int F = -(matrix[0][0] * matrix[2][1] - matrix[0][1] * matrix[2][0]);
            int G = (matrix[0][1] * matrix[1][2] - matrix[1][1] * matrix[0][2]);
            int H = -(matrix[0][0] * matrix[1][2] - matrix[0][2] * matrix[1][0]);
            int I = (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]);

            System.out.println(A);
            System.out.println(B);
            System.out.println(C);
            System.out.println(D);
            System.out.println(E);
            System.out.println(F);
            System.out.println(G);
            System.out.println(H);
            System.out.println(I);
//            System.out.println("Matriks Kunci :");
//            System.out.println(matriks[0][0] + " " + (matriks[0][1]));
//            System.out.println(matriks[1][0] + " " + (matriks[1][1]));
//            System.out.println("Invers K = " + "multiplikatif x " + d + " " + b);
//            System.out.println("                           " + c + " " + a);

            matrikInvers[0][0] = A;
            matrikInvers[0][1] = D;
            matrikInvers[0][2] = G;
            matrikInvers[1][0] = B;
            matrikInvers[1][1] = E;
            matrikInvers[1][2] = H;
            matrikInvers[2][0] = C;
            matrikInvers[2][1] = F;
            matrikInvers[2][2] = I;

            // mencari nilai multiplikative determinan, multiplikatif diperlukan agar hasil invers 
            // tidak menjadi bilangan pecahan. 
            BigInteger Multiplikatif = BigInteger.valueOf(determinan).modInverse(BigInteger.valueOf(modulo));

            int MultiplikatifDet = Multiplikatif.intValue();

            System.out.println("MultiPlikatif = " + MultiplikatifDet);

            for (int i = 0; i < matrikInvers.length; i++) {
                for (int j = 0; j < matrikInvers[i].length; j++) {
                    if (matrikInvers[i][j] < 0) {
                        matrikInvers[i][j] = modulo - (Math.abs(matrikInvers[i][j]) % modulo);
                    } else {
                        matrikInvers[i][j] = matrikInvers[i][j] % modulo;
                    }
                    matrikInvers[i][j] = (int) (matrikInvers[i][j] * MultiplikatifDet);
                    matrikInvers[i][j] = matrikInvers[i][j] % modulo;

                    // System.out.println();
                }
                //System.out.println("");
            }

            System.out.println("Matriks Invers = ");

            // menampilkan invers matrik 
            for (int i = 0; i < matrikInvers.length; i++) {
                for (int j = 0; j < matrikInvers[i].length; j++) {
                    System.out.print(matrikInvers[i][j] + " ");
                }
                System.out.println("");
            }

        }
        return determinan;
    }

Selain source code, saya lampirkan screenshot proses enkripsi hill cipher. Plainteks sebagai teks asli yang disandikan tertulis sebagaimana contoh pada Gambar 2.

Gambar 2. Enkripsi Hill Cipher Matriks Kunci 3x3

Jika teman-teman ada yang bertanya, mengapa hasil yang ditunjukkan cipherteks memunculkan karakter kotak-kotak kosong begitu? Jika teman-teman perhatikan tabel ASCII-nya, maka akan menemukan karakter khusus yang sulit ditulis. Walaupun netbeans gagal menuliskannya, namun perhitungan enkripsi dan dekripsi sama sekali tidak terganggu. Teman-teman bisa cek program lengkapnya. 

Kemudian dilanjutkan ke proses dekripsi untuk mengembalikan cipherteks ke bentuk aslinya sebelum disandikan. 

Gambar 3. Dekripsi Hill Cipher Matriks Kunci 3x3

Jika teman-teman berminat untuk mempelajari atau mengembangkannya, silakan minta saja via WA. Saya sangat sedang jika program ini dikembangkan menjadi bentuk baru yang lebih canggih, baik dari sisi keamanan persandiannya ataupun pengembangan platformnya. Ubah jadi platform berbasis web atau mobile android. Pasti keren tuh.


Biarf lebih complete, sekalian saya tunjukin video demo project-nya:



    

1 comment

Terima kasih telah mampir di blog kami. Jika ingin menghubungi penulis, silakan kirim pesan via email di kitainformatika@gmail.com atau via WA di 087750503014. Jika mood penulis lagi baik, biasanya fast respon.
Comment Author Avatar
Anonymous
February 20, 2020 at 3:51 AM Delete
could you share de code please msirmec@gmail.com