Kriptografi - Program Bahasa C untuk Menyembunyikan Pesan Menggunakan Teknik Caesar Cipher dan Vigenere Cipher

Kriptografi adalah seni menyembunyikan/menyamarkan pesan seolah-olah pesan tersebut tidak memiliki makna yang bertujuan untuk keamanan informasi dari pihak-pihak yang tidak diinginkan.

Istilah-istilah umum dalam kriptografi
Plaintext    : pesan yang ingin dirahasiakan.
Ciphertext : pesan yang telah disamarkan.
Encryption: proses penyamaran dari plaintext ke ciphertext.
Decryption: proses pembalikan dari ciphertext ke plaintext.



Contoh











Kriptografi sudah lama digunakan oleh tentara Sparta di Yunani pada permulaan 400 SM. Mereka menggunakan alat yang disebut scytale. Alat ini terdiri dari sebuah pita panjang dari daun papyrus yang dililitkan pada sebatang silinder. Pesan yang akan dikirim ditulis horizontal (baris per baris). Bila pita dilepaskan, maka huruf-huruf di dalamnya telah tersusun membentuk pesan rahasia.

Untuk membaca pesan, penerima melilitkan kembali silinder yang diameternya sama dengan diameter silinder pengirim. Teknik kriptografi seperti ini dikenal dengan nama transposition cipher, yang merupakan metode enkripsi tertua.

Transposition Cipher

Algoritma Kriptografi(cipher) adalah fungsi matematika yang digunakan untuk enkripsi dan dekripsi. Kekuatan suatu algoritma kriptografi diukur dari banyaknya kerja yang dibutuhkan untuk memecahkan data ciphertext menjadi plaintext.
Kriptografi modern tidak lagi mendasarkan kekuatan pada algoritmanya. Jadi algoritma tidak dirahasiakan. Kekuatan kriptografinya terletak pada kunci, yang berupa deretan karakter atau bilangan bulat yang dijaga kerahasiannya.

Misalnya dengan menggunakan teknik Caesar Cipher, yaitu teknik menyembunyikan pesan dengan menggeser susunan alphabet sejauh k huruf. Jika kunci(k) bernilai 3, maka huruf-huruf pada plaintext digeser sejauh 3 huruf.


Dengan kata lain, misalkan p adalah plaintext, pi adalah huruf ke-i pada plaintext, dan k adalah kunci rahasianya, maka pergeseran tiap huruf plaintext menjadi ciphertext(c), yaitu ci, adalah sebagai berikut: 

ci = (pi + k) % 26

Komputer hanya mengerti angka, jadi angka-angka itu harus direpresentasikan menjadi karakter agar dapat dipahami oleh manusia. Daftar representasi angka-angka tersebut dapat kita lihat pada tabel ASCII berikut ini


Perhatikan pada angka 65 - 90 dan 97 - 122 pada kolom dec(desimal). Huruf-huruf pada abjad direpresentasikan oleh angka-angka pada range tersebut. 65 - 90 merepresentasikan huruf kapital, sedangkan 97 - 122 merepresentasikan huruf kecil. Jadi perhitungan yang dilakukan di komputer akan menjadi seperti ini

if (plain[i] >= 'A' && plain[i] <= 'Z')
{
   // pada ASCII, huruf A dimulai dari 65, maka kurangi sejauh A yaitu 65 ketika di-modulo
   // lalu ditambah sejauh A yaitu 65 agar yang tampil adalah huruf 
   // karena pada ASCII huruf kapital dimulai dari 65
   cipher = ((plain[i] + key - 'A') % 26) + 'A';
}
else if (plain[i] >= 'a' && plain[i] <= 'z')
{
   // pada ASCII, huruf a dimulai dari 97, maka kurangi sejauh a yaitu 97 ketika di-modulo
   // lalu ditambah sejauh a yaitu 97 agar yang tampil adalah huruf 
   // karena pada ASCII huruf kecil dimulai dari 97
   cipher = ((plain[i] + key - 'a') % 26) + 'a';
}

Perhatikan rumus yang dilabeli dengan warna kuning, kita dapat melakukan perhitungan menggunakan huruf karena sejatinya huruf merupakan representasi dari angka. Mengapa perlu dikurang A dan ditambah lagi dengan A pada perhitungan diatas? Misalnya plaintext-nya adalah A, dan key-nya 3, maka ketika dihitung cipher = (65 + 3) % 26 = 16. Maka menurut tabel ASCII yang tampil bukan huruf D melainkan DLE(Data Link Escape) yang direpresentasikan oleh angka 16. Maka dari itu perlu dikurang A dan ditambah lagi dengan A, perhitungannya akan menjadi cipher = ((65 + 3 - 65) % 26) + 65 = 68, sehingga yang tampil menurut tabel ASCII adalah huruf D. Begitu juga pada perkondisian yang mengenkripsi huruf kecil.

Program yang menggunakan teknik Caesar Cipher dengan nama caesar.c
#include <stdio.h>
#include <string.h> // agar dapat menggunakan strlen()

int main()
{
    // input kunci
    int key;
    printf("Key: ");
    scanf("%d", &key);

    // input plaintext
    char plain[77];
    printf("Plaintext: ");
    gets(plain); // get string, untuk menginput string

    // angka pada ciphertext di-inisialisasi 0
    int cipher = 0;

    // strlen(), fungsi yang menghitung panjang string
    // pengulangan untuk mengenkripsi huruf per huruf
    for (int i = 0; i < strlen(plain); i++)
    {
        cipher = plain[i];

        // jangan di-enkripsi jika huruf pada plaintext berupa spasi
        if (plain[i] == ' ')
        {
            cipher = ' ';
        }

        // perkondisian supaya hanya huruf-huruf pada alphabet yang terenkripsi
        // sesuai dengan kode pada tabel ASCII
        else if (plain[i] >= 'A' && plain[i] <= 'Z')
        {
            // pada ASCII, huruf A dimulai dari 65, maka kurangi sejauh A yaitu 65 ketika di-modulo
            // lalu ditambah sejauh A yaitu 65 agar yang tampil adalah huruf 
            // karena pada ASCII huruf kapital dimulai dari 65
            cipher = ((plain[i] + key - 'A') % 26) + 'A';
        }
        else if (plain[i] >= 'a' && plain[i] <= 'z')
        {
            // pada ASCII, huruf a dimulai dari 97, maka kurangi sejauh a yaitu 97 ketika di-modulo
            // lalu ditambah sejauh a yaitu 97 agar yang tampil adalah huruf 
            // karena pada ASCII huruf kecil dimulai dari 97
            cipher = ((plain[i] + key - 'a') % 26) + 'a';
        }

        // tampilkan huruf yang telah digeser(di-enkripsi)
        // nilai bertipe data integer dapat ditampilkan menggunakan %c 
        // agar yang tampil adalah karakter sesuai tabel ASCII
        printf("%c", cipher);
    }

    printf("\n");

    return 0;
}

Output program ketika di-run
root@kali: ./caesar
Key: 3
Plaintext: awasi asterix dan temannya obelix
Ciphertext: dzdvl dvwhula gdq whpdqqbd rehola
root@kali: ./caesar
Key: 14
Plaintext: Temui aku di kolong jembatan pukul sembilan malam
Ciphertext: Hsaiw oyi rw yczcbu xsapohob diyiz gsapwzob aozoa
root@kali:

Teknik lain yang lebih kuat adalah Vigenere Cipher. Teknik ini kurang lebih sama dari Caesar Cipher namun yang menjadi kunci adalah string.

Misalnya kita memiliki plaintext "I like you" dan kunci "panda", ketika di-enkripsi huruf per huruf, maka huruf I pada plaintext akan di-enkripsi oleh huruf p pada kunci. Lalu huruf l pada plaintext akan di-enkripsi dengan huruf a pada kunci, dan seterusnya. Jika kunci telah sampai ke huruf terakhir, maka kembali ke awal.

Perlu diingat kembali bahwa huruf direpresentasikan oleh angka. Jadi, misalkan kita ingin menggeser huruf sebanyak B maka akan tergeser sejauh 66, karena kunci yang kita gunakan adalah huruf. Maka dari itu kurangi sebesar A, yaitu 65, sehingga akan bergeser sejauh 1.

Program yang menggunakan teknik Vigenere Cipher dengan nama vigenere.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    // input kunci
    char key_str[25];
    printf("Enter key: ");
    gets(key_str);

    // input plaintext
    char plain[77];
    printf("Enter plain text: ");
    gets(plain);

    // inisialisasi cipher sama dengan 0
    int cipher = 0;
    
    // variabel untuk menandakan indeks pada kunci
    int j = 0;

    printf("Cipher text: ");
    for (int i = 0; i < strlen(plain); i++)
    {
        // indeks (huruf ke-i) pada kunci yang digunakan untuk mengenkripsi plainteks
        int index = j % strlen(key_str);
        int key = key_str[index];

        // karena huruf alphabet berjumlah 26, maka kunci dikurangi dengan 65(huruf kapital)
        if (key_str[index] >= 'A' && key_str[index] <= 'Z')
        {
            key = key - 'A';
        }
        
        // karena huruf alphabet berjumlah 26, maka kunci dikurangi dengan 97(huruf kecil)
        else if (key_str[index] >= 'a' && key_str[index] <= 'z')
        {
            key = key - 'a';
        }

        // jangan pindah ke huruf selanjutnya pada key jika huruf pada plaintext adalah selain alphabet
        if ((plain[i] >= 'A' && plain[i] <= 'Z') || (plain[i] >= 'a' && plain[i] <= 'z'))
        {
            j++;
        }

        cipher = plain[i];
        
        // jangan di-enkripsi jika huruf pada plaintext adalah spasi
        if (plain[i] == ' ')
        {
            cipher = ' ';
        }
        
        // jangan di-enkripsi jika huruf pada plaintext adalah selain huruf alphabet
        else if (plain[i] < 'A' || (plain[i] > 'Z' && plain[i] < 'a') || plain[i] > 'z')
        {
            cipher = plain[i];
        }
        
        // perkondisian untuk mengenkripsi huruf alphabet
        else if (plain[i] >= 'A' && plain[i] <= 'Z')
        {
            cipher = ((plain[i] + key - 'A') % 26) + 'A';
        }
        else if (plain[i] >= 'a' && plain[i] <= 'z')
        {
            cipher = ((plain[i] + key - 'a') % 26) + 'a';
        }

        printf("%c", cipher);
    }

    printf("\n");

    return 0;
}

Output program ketika di-run
root@kali: ./vigenere
Enter key: panda
Enter plain text: I like you
Cipher text: X lvne noh
root@kali: ./vigenere
Enter key: senpai
Enter plain text: notice me, senpai!
Cipher text: fsgxcm ei, ftnxsm!
root@kali:

3 comments

kenpa harus dimod kan, kenpa tidak langusng saja misal A=65 tambah key =3 jadi 68?

Reply

lha untuk decoder nya gimana gan?

Reply

Post a Comment