Kriptografi Teks Berbasis Android Menggunakan Algoritma Hill Cipher

Table of Contents
Postingan kali ini berbeda dari biasanya. Bahkan menurut saya, ini tonggak sejarah baru bagi blog ini dalam hal mengimplementasikan algoritma. Jika sebelumnya saya selalu memilih platform java dekstop dalam memberikan contoh penerapan algoritma, maka kali ini saya memilih platform java android menggunakan IDE populer macam Android Studio. Saya pun memahami jika tugas-tugas perkuliahan bidang komputer mengalami perkembangan pesat, salah satunya adalah menjamurnya tugas untuk mengimplementasikan algoritma tertentu pada platform Android. Tidak hanya pada mata kuliah pemrograman perangkat bergerak, bahkan untuk mata kuliah lainnya. Semoga postingan ini bermanfaat bagi teman-teman mahasiswa bidang komputer. 

Algoritma yang dipilih adalah algoritma kriptografi yang laris ditanyakan serta diminta source code-nya di blog saya. Apalagi jika bukan Hill Cipher, padahal algoritma ini tergolong kriptografi klasik. Jika ada waktu, saya akan menerangkan algoritma kriptografi klasik dan modern lainnya, tentu dengan contoh implementasi berbasis desktop atau android. Kebiasaan mahasiswa komputer adalah menyalin source code yang ditemukan di dunia maya, lalu di-paste dalam project-nya. Kalau cocok ya syukur, kalau tidak ya coba lagi. Sepengalaman saya dulu seperti itu. Kalau source code dalam postingan ini cocok untuk tugas atau skripsi, ya silakan saja.

Manakala hill cipher diimplementasikan pada java desktop, tentu ini hal yang biasa. Mulai tidak biasa ketika diterapkan pada java android, walaupun skripsi tentang hal ini mulai menjamur tapi tutorial bagaimana langkah-langkah penerapan, sangatlah minim. Berikut contoh tampilan hasil implementasinya:

Gambar 1. Implementasi Kriptografi Hill Cipher pada Android Studio

Gambar 1 menunjukkan tampilan program hill cipher ketika dijalankan pada emulator android. Saya kurang berbakat dalam merancang desain user interface yang elok dipandang. Oleh karenanya, mohon maaf jika tampilan layout-nya jelek. Coba saya bahas satu per satu alur proses perancangan aplikasinya, yang secara umum dibagi menjadi 3 tahapan, yaitu 1) Merancang user interface (layout aplikasi android), 2) Pemrograman java untuk hill cipher, 3) Uji coba.

Merancang user interface

Proses merancang user interface cukup simpel. Saya hanya membuat project baru bertipe Basic Activity. Lalu pada content_main.xml, saya tambahkan komponen berikut:

  • EditText untuk input plainteks atau cipherteks
  • EditText untuk input Kunci 1, 2, 3, 4. Mengapa tidak menjadi satu baris horizontal saja? Kok malah vertikal begitu? Nah, itulah ketidakahlian saya. Tolong diajari ya. 
  • Button untuk Enkripsi, Deskripsi dan Reset
  • EditText untuk output plainteks atau cipherteks
  • Button untuk copy, maksudnya adalah menyalin output cipherteks agar secara otomatis tampil kembali pada EditText input.  
Saya yakin, teman-teman bisa dengan mudah membuat layout tersebut. xml-nya tidak perlu saya share ya.

Pemrograman java untuk hill cipher

Langkah ini cukup menarik dan menantang. Saya beruntung sebelumnya pernah membuat source code hill chiper pada java desktop. Karena sama-sama menggunakan java, maka source code saya sebelumnya tinggal saya copy paste ke android studio. Tentu dengan sedikit polesan. Sama-sama java tapi platform berbeda. Ada source code java desktop yang tidak berfungsi pada java android, jika saya paksakan, akan menjadi bug dan error. Padahal digunakan untuk hill cipher. Contohnya adalah JOptionPane.

Postingan ini tidak menerangkan masalah teori atau perhitungan manual hill cipher ya. Jangan salah paham dulu. Hanya menjelaskan pengimplementasian saja. Saya amat menyarankan teman-teman untuk belajar perhitungan manual hill cipher sebelum masuk ke source code. Harapannya satu, meminimalisir kebingungan. Perhitungan manual dan contoh source code hill cipher dapat teman-teman temukan pada artikel saya sebelumnya:

  1. Implementasi Enkripsi Teks Menggunakan Algoritma Hill Chiper Pada Java
  2. Implementasi Deskripsi Teks Menggunakan Algoritma Hill Chiper Pada Java  

Pada Gambar 1, terlihat bahwa class yang digunakan dalam aplikasi ini berjumlah 3 class, yaitu
deskripsi.java
enkripsi.java
ActivityMain.java

Berikut saya berikan contoh source code untuk ActivityMain.java


package com.example.hillchiper;

import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.math.BigInteger;

public class MainActivity extends AppCompatActivity {

    deskripsi des = new deskripsi();
    enkripsi en = new enkripsi();
    EditText K1, K2, K3, K4, awal, akhir;
    int kunci[][] = new int[2][2];
    int[][] matrikInvers = new int[2][2];

    String hasilEn = "" ;
    String hasilDes = "";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        K1 = (EditText)findViewById(R.id.K1);
        K2 = (EditText)findViewById(R.id.K2);
        K3 = (EditText)findViewById(R.id.K3);
        K4 = (EditText)findViewById(R.id.K4);
        awal = (EditText)findViewById(R.id.teksAwal);
        akhir = (EditText)findViewById(R.id.teksAkhir);



        Button klikDeskrip = findViewById(R.id.deskrip);
        klikDeskrip.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                int k1 = Integer.parseInt(K1.getText().toString());
                int k2 = Integer.parseInt(K2.getText().toString());
                int k3 = Integer.parseInt(K3.getText().toString());
                int k4 = Integer.parseInt(K4.getText().toString());

                kunci[0][0] = k1;
                kunci[0][1] = k2;
                kunci[1][0] = k3;
                kunci[1][1] = k4;

                int HitungInvers = hitungInvers(kunci);

                if(HitungInvers<=0){
                    //akhir.setText(Integer.toString(""));
                    akhir.setText("Kunci Tidak Memenuhi Syarat");
                }else{
                    hasilDes = des.hitungDeskripsi(awal.getText().toString(),kunci);
                    akhir.setText(hasilDes);
                }
            }
        });


        Button klikEnkrip = findViewById(R.id.enkrip);
        klikEnkrip.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                int k1 = Integer.parseInt(K1.getText().toString());
                int k2 = Integer.parseInt(K2.getText().toString());
                int k3 = Integer.parseInt(K3.getText().toString());
                int k4 = Integer.parseInt(K4.getText().toString());

                kunci[0][0] = k1;
                kunci[0][1] = k2;
                kunci[1][0] = k3;
                kunci[1][1] = k4;

                int HitungInvers = hitungInvers(kunci);

                if(HitungInvers<=0){
                    //akhir.setText(Integer.toString(""));
                    akhir.setText("Kunci Tidak Memenuhi Syarat");
                }else{
                   hasilEn = en.hitungEnkripsi(awal.getText().toString(),kunci);
                   akhir.setText(hasilEn);
                }
            }
        });

        Button reset = findViewById(R.id.reset);
        reset.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                K1.setText("");
                K2.setText("");
                K3.setText("");
                K4.setText("");
                awal.setText("");
                akhir.setText("");

            }
        });

        Button copy = findViewById(R.id.copy);
        copy.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
              awal.setText(akhir.getText());
                akhir.setText("");
            }
        });

    }

    static int modulo = 256;

    public int hitungInvers(int[][] matriks) {
        int determinan = (matriks[0][0] * matriks[1][1]) - (matriks[0][1] * matriks[1][0]);
        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) {
            System.out.println("Kunci Tidak Memenuhi Syarat");
        } else {


            int d = matriks[1][1];
            int c = -(matriks[1][0]);
            int b = -(matriks[0][1]);
            int a = (matriks[0][0]);

            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] = d;
            matrikInvers[0][1] = b;
            matrikInvers[1][0] = c;
            matrikInvers[1][1] = a;


            // 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[0].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[0].length; j++) {
                    System.out.print(matrikInvers[i][j] + " ");
                }
                System.out.println("");
            }

        }
        return determinan;
    }
}

Pada class ActivityMain.java terdapat method untuk menghitung determinan kunci hill cipher. Kunci yang digunakan adalah kunci matriks berordo 2x2. Method menghitung determinan dimaksudkan untuk memeriksa kunci hill cipher, apakah memenuhi syarat atau tidak. Karena syarat kunci adalah nilai determinan >0. Silakan teman-teman kontak saya via WA atau email jika ada kendala dalam mengimplementasikan hill cipher menggunakan Android Studio.

Uji Coba Aplikasi

Aplikasi hill cipher berbasis android kemudian di-running melalui emulator. Bisa juga langsung melalui smartphone teman-teman. API terendah saya setting Android Ice Cream Sandwitch. Jika kurang dari itu, aplikasi gagal running, walaupun bisa juga di-setting ulang. 

Gambar 2. Implementasi Enkripsi Hill Cipher 

Gambar 2 menunjukkan implementasi enkripsi hill cipher untuk mengubah plainteks menjadi cipherteks. Yaitu mengubah kata yang dapat dipahami menjadi kata yang tersandikan. Kunci yang digunakan adalah matriks berordo 2x2. Oleh karenanya ada 4 EditText untuk masukan kunci,  secara berurutan adalah kunci 1 (baris 1 kolom 1), kunci 2 (baris 1 kolom 2), kunci 3 (baris 2 kolom 1), kunci 4 (baris 2 kolom 2). Kemudian di klik Button Enkripsi, untuk menampilkan cipherteks hasil eksekusi hill chiper. 

Gambar 3. Implementasi Deskripsi Hill Cipher 

Sementara itu, Gambar 3 menunjukkan sebaliknya, yaitu proses deskripsi untuk mengubah cipherteks menjadi plainteks. Untuk mempermudah pengguna, saya menambahkan button copy, yang berfungsi untuk menyalin cipherteks ke EditText input. Hal ini bertujuan untuk memeriksa kembali, cipherteks dapat kembali ke plainteks asal atau tidak. Baik, itu saja yang dapat saya jelaskan. Jangan pernah menyerah jika teman-teman mendapatkan tugas yang sulit, semua ada solusinya!

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
August 21, 2019 at 8:39 AM Delete
Mantap penjelasannya....