Implementasi Enkripsi Teks Menggunakan Algoritma Hill Chiper Pada Java

Kriptografi adalah ilmu yang mempelajari teknik-teknik matematika yang berhubungan dengan aspek keamanan informasi seperti kerahasiaan, integritas data, serta otentikasi (Rinaldi Munir, 2006). Dalam implementasinya, kriptografi memiliki dua macam algoritma, yaitu: algoritma simetris dan algoritma asimetris. Salah satu algoritma kriptografi yang cukup populer untuk penyandian data adalah algoritma Hill Chiper. Hill Chiper tergolong sebagai algoritma kunci simetris yang menggunakan matriks berukuran m x m sebagai kunci untuk melakukan enkripsi dan dekripsi. Dasar teori matriks yang digunakan dalam Hill Cipher antara lain adalah perkalian antar matriks dan melakukan invers pada matriks. 


Proses enkripsi pada Hill Cipher dilakukan per blok plaintext. Ukuran blok tersebut sama dengan ukuran matriks kunci. Sebelum membagi teks menjadi deretan blok-blok, plaintext terlebih dahulu dikonversi menjadi angka, masing-masing sehingga A=0, B=1, hingga Z=25 (Hasugian, 2013).

Gambar 1. Pasangan Huruf dan Angka untuk konversi
Secara matematis, proses enkripsi pada Hill Cipher didapatkan melalui perkalian kunci dan plaintext:
C = K . P
C = Ciphertext
K = Kunci
P = Plaintext

Gambar 2. Ilustrasi Enkripsi Hill Chiper (sumber : Hasugian, 2013)
kunci yang saya gunakan untuk perhitungan hill chiper adalah matrik dengan ordo 2x2. Sebelum plaintext dikalikan dengan matrik kunci, proses awal dalam enkripsi hill chiper adalah merubah plaintext yang berupa huruf kedalam bentuk angka sesuai dengan pasangan konversi pada gambar 1. Pasangan huruf A adalah angka 0, huruf B adalah angka 1 dan seterusnya hingga huruf Z yang berpasangan dengan angka 25.

Misal, plaintext yang diberikan adalah MALANG. Maka MALANG harus ditransformasikan dahulu ke dalam bentuk angka.
M = 12
A = 0
L = 11
A = 0
N = 13
G = 6

Sehingga plaintext MALANG berubah menjadi 12,0,11,0,13,6. Kemudian, karena matrik kunci telah ditentukan dengan ordo 2x2 yang memiliki 2 kolom, maka deretan angka 12,0,11,0,13,6 dipecah tiap 2 angka. Hasil pembagian blok adalah :



Sampai disini, plaintext telah bertransformasi menjadi bentuk angka dan telah dipecah menjadi 3 blok matrik, dengan demikian plaintext tiap blok matrik akan dikalikan dengan matrik kunci. Berdasarkan metrik kunci ordo 2x2, saya menetapkan matrik kuncinya adalah {{5,6},{2,3}}.

Perlu dicermati : Saya menyarankan agar dalam pemilihan matrik kunci, jangan sampai matrik kunci yang dipilih menghasilkan determinan 0 maupun determinan minus. Hal ini berguna untuk memperlancar perhitungan perkalian enkripsi maupun deskripsi hill chiper. Determinan dapat dihitung dengan cara : det(A) = ad-bc, maka matrik kunci {{5,6},{2,3}} menghasilkan determinan (5x3 - 6x2) = 15-12 = 3. Sehingga nilai determinan matrik kunci {{5,6},{2,3}} tidak termasuk 0 maupun minus.

Kembali ke rumus enkripsi hill chiper, bahwa chipertext =  matrik kunci * blok matrik(plaintext) atau C = K x P. Maka perhitungan chipertext adalah :

Untuk K*P(MA)




Untuk K*P(LA)




Untuk K*P(NG)




Hasil dari perkalian plaintext dengan matrik kunci selanjutnya di modulo dengan angka 26. Mengapa angka 26? karena jumlah pasangan huruf dan angka untuk konversi sebagaimana pada gambar 1 sebanyak 26. Jika nantinya pasangan konversi berjumlah lebih dari 26. Maka modulo yang digunakan tidak lagi 26, melainkan sebanyak jumlah pasangan konversi.

Berdasarkan hasil akhir modulo 26, diperoleh angka 8,24,3,22,23,18. Jika angka-angka tersebut ditransformasikan lagi dalam bentuk huruf berdasarkan tabel konversi pada gambar 1. Diperoleh huruf I,Y,D,W,X,S.

Dapat disimpulkan bahwa, hasil enkripsi hill chiper untuk plaintext MALANG adalah chipertext IYDWXS.

Untuk mempermudah perhitungan enkripsi hill chiper, saya telah membuatkan program enkripsi hill chiper menggunakan pemrograman java. Bagi teman-teman yang membutuhkan untuk tugas akhir, tugas kuliah maupun penelitian silakan digunakan dengan bebas dengan tetap mencantumkan referensi sumber kode.

Sama halnya dengan perhitungan manual diatas, untuk uji coba sumber kode enkripsi hill chiper, masukan plaintext yang saya berikan adalah MALANG

/**
 *
 * @author CHARIS
 */
public class HillChiper_Enkripsi {

    static String[] abjad = {"A", "B", "C", "D", "E", "F", "G", "H",
        "I", "J", "K", "L", "M", "N", "O", "P", "Q",
        "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
        };

    static int[] angka = {0, 1, 2, 3, 4,
        5, 6, 7, 8, 9,
        10, 11, 12, 13, 14,
        15, 16, 17, 18, 19,
        20, 21, 22, 23, 24, 25
        };

    static int modulo = 26;

    static String[] teks2karakter;
    static String hasilKonversi[][];
    static String hasilHitungKunci[][];
    static String totalHasilEnkrip = "";

    public String hitungEnkripsi(String text, int[][] kunci) {
        System.out.println("Plaintext : " + text);
        // String hasilSpasi = hilangkanSpasi(text);
        hitungJumlahHuruf(text);
        pisahkanTeks(text);
        AbjadKeAngka(teks2karakter);
        perhitunganKunci(hasilKonversi, kunci);
        AngkaKeAbjad(hasilHitungKunci);

        return totalHasilEnkrip;
    }

    static String hilangkanSpasi(String text) {
        String hasil = text.replaceAll("\\s+", "");
        return hasil;
    }

    public int hitungJumlahHuruf(String text) {
        int jumlahHuruf = text.length();
        System.out.println("Jumlah huruf : " + jumlahHuruf);
        return jumlahHuruf;
    }

    static String pisahkanTeks(String text) {
        System.out.println("========== MEMBAGI TIAP 2 HURUF  ===========");
        String teksnya = text;
        if (teksnya.length() % 2 == 0) {
            teksnya = text;
        } else {
            teksnya = text + ".";
        }
        assert teksnya.length() % 2 == 0;
        teks2karakter = new String[teksnya.length() / 2];
        for (int index = 0; index < teks2karakter.length; index++) {
            teks2karakter[index] = teksnya.substring(index * 2, index * 2 + 2);
            System.out.println(teks2karakter[index]);
        }
        return teksnya;
    }

    static String[][] AbjadKeAngka(String[] text) {
        hasilKonversi = new String[text.length][2];
        System.out.println("========== TRANSFORMASI HURUF KE ANGKA  ===========");
        for (int i = 0; i < text.length; i++) {
            String char1 = text[i].substring(0, 1);
            String char2 = text[i].substring(1);

            for (int j = 0; j < abjad.length; j++) {
                if (char1.equals(abjad[j])) {
                    char1 = String.valueOf(angka[j]);
                }
                if (char2.equals(abjad[j])) {
                    char2 = String.valueOf(angka[j]);
                }
            }

            if (hasilKonversi[i][0] == null) {
                hasilKonversi[i][0] = char1;

                if (hasilKonversi[i][1] == null) {
                    hasilKonversi[i][1] = char2;

                }
            }
        }

        for (int n = 0; n < hasilKonversi.length; n++) {
            for (int p = 0; p < hasilKonversi[0].length; p++) {
                System.out.print(hasilKonversi[n][p] + " ");
            }
            System.out.println("");
        }

        return hasilKonversi;
    }

    static String[][] perhitunganKunci(String[][] angka, int[][] kunci) {
        int kunciK0B0 = kunci[0][0];
        int kunciK0B1 = kunci[0][1];
        int kunciK1B0 = kunci[1][0];
        int kunciK1B1 = kunci[1][1];

        hasilHitungKunci = new String[angka.length][2];
        // int hasil = (kunci[0][0]*plain[0]) + (kunci[0][1]*plain[1]) ;
        // int hasil1 = (kunci[1][0]*plain[0]) + (kunci[1][1]*plain[1]) ;
        System.out.println("========== HASIL PERKALIAN KUNCI ===========");
        for (int n = 0; n < angka.length; n++) {
            int konvert = Integer.parseInt(angka[n][0]);
            int konvert1 = Integer.parseInt(angka[n][1]);
            int hasil = (kunciK0B0 * konvert) + (kunciK0B1 * konvert1);
            int hasil1 = (kunciK1B0 * konvert) + (kunciK1B1 * konvert1);
            
            System.out.println(hasil + " " + hasil1);
            
            hasil = hasil % modulo;
            hasil1 = hasil1 % modulo;
            
            
            //   System.out.println(hasil + " " + hasil1);

            if (hasilHitungKunci[n][0] == null) {
                hasilHitungKunci[n][0] = String.valueOf(hasil);
                if (hasilHitungKunci[n][1] == null) {
                    hasilHitungKunci[n][1] = String.valueOf(hasil1);
                }
            }
        }

        System.out.println("========== HASIL MODULO 26 ===========");
        
        for (int i = 0; i < hasilHitungKunci.length; i++) {
            for (int j = 0; j < hasilHitungKunci[0].length; j++) {
                System.out.print(hasilHitungKunci[i][j] + " ");
            }
            System.out.println("");
        }
        return hasilHitungKunci;
    }

    static String AngkaKeAbjad(String[][] hasilHitungKunci) {

        String hasilEnkripsi = "";

        System.out.println("========== HASIL ENKRIPSI ===========");
        totalHasilEnkrip = "";
        for (int i = 0; i < hasilHitungKunci.length; i++) {
            for (int j = 0; j < hasilHitungKunci[0].length; j++) {
                // System.out.print(hasilHitungKunci[i][j]+" ");
                for (int k = 0; k < angka.length; k++) {
                    if (hasilHitungKunci[i][j].equals(String.valueOf(angka[k]))) {
                        hasilEnkripsi = abjad[k];
                        totalHasilEnkrip = totalHasilEnkrip + hasilEnkripsi;
                    }
                }
            }
        }
        System.out.println(totalHasilEnkrip);
        return totalHasilEnkrip;
    }

    public static void main(String[] args) {
        String text = "MALANG";
        int[][] kunci = {{5, 6}, {2, 3}};
        new HillChiper_Enkripsi().hitungEnkripsi(text, kunci);
    }
}

Hasil keluaran dari sumber kode enkripsi hill chiper diatas sama persis dengan perhitungan manual.

Gambar 3 Hasil enkripsi hill chiper

























Catatan : 
Enkripsi hill chiper sebagaimana yang telah dijabarkan diatas tentu berjalan dengan baik andaikata plaintext yang diberikan sesuai dengan tabel konversi pada gambar 1, yaitu plaintext terdiri atas huruf kapital dengan jumlah karakter bernilai genap. Contoh : plaintext MALANG, terdiri atas huruf kapital dengan jumlah karakter 6 (genap).

Namun, andaikata input plaintext adalah :

  1. Huruf dengan jumlah karakter ganjil, misal : MOJOKERTO, 9 huruf (ganjil) 
  2. Terdiri dari kombinasi huruf besar maupun kecil, misal : Malang
  3. Memiliki tanda baca titik maupun spasi, misal : Malang Kota Bunga.
Berdasarkan tambahan jenis plaintext diatas, tentu jika diimplementasikan menggunakan tabel konversi pada gambar 1 tidak akan bisa, dan menghasilkan chiper text yang tidak akurat. Solusinya adalah dengan merubah tabel konversi sehingga memperbanyak jumlah pasangan konversi. Contoh penambahan pasangan konversi adalah pada gambar 4 berikut, yaitu penambahan pada simbol titik (.) berpasangan dengan angka 26, dan simbol spasi (" ") pada angka 27.

Gambar 4 Penambahan pasangan konversi
Contoh implementasi enkripsi hill chiper menggunakan plaintext huruf kecil, huruf kapital, simbol titik dan spasi terdapat pada gambar 5 berikut. 

Aplikasi Enkripsi Hill Chiper dengan tambahan huruf kecil, huruf besar dan spasi
Semoga penjelasan ringkas tentang enkripsi hill chiper ini bermanfaat bagi teman-teman, silakan hubungi saya via email maupun WhatApp jika ada hal-hal yang perlu didiskusikan. Untuk menjelasan mengenai deskripsi hill chiper akan saya sampaikan secara terpisah dipostingan lain.

Referensi :
  • Enkripsi dan Deskripsi menggunakan Hill Chiper, pandiangan-m.blogspot.co.id diakses tanggal 14 Agustus 2016
  • Munir, Rinaldi. 2006. Kriptografi. Bandung : Informatika.
  • Hasugian, Abdul Halim. 2013. Implementasi Algoritma Hill Chiper dalam Penyandian Data. Pelita Informatika Budi Darma, Volume : IV, Nomor: 2, Agustus 2013 ISSN : 2301-9425 
Lihat juga demo program Enkripsi dan Deskripsi menggunakan Algoritma Hill Chiper di Channel Youtube Informatika Kita


Subscribe to receive free email updates:

5 Responses to "Implementasi Enkripsi Teks Menggunakan Algoritma Hill Chiper Pada Java"

  1. gan boleh minta source code yang pakai form gan...???
    buat tugas kuliah gan

    ReplyDelete
  2. Gan, boleh minta source kode vb net?
    Buat referensi tugas kuliah gan
    Plisss
    Email : aiinanrawanii@gmail.com

    ReplyDelete
  3. mas itu perhitungan matrix nya apa gk salah ya?

    ReplyDelete

Terima Kasih Telah Berkunjung, Silakan Berkomentar...
Kritik dan Saran Teman-Teman Sangat Memotivasi Saya (^_^)