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:

Materi Pemrograman Bahasa C



Materi bahasa pemrograman C yang sudah saya susun sedemikian rupa, silahkan dipelajari dan dipahami. Susunan materi ini akan terus di-update dengan materi baru di waktu yang akan datang.
Semoga bermanfaat^^
 
I/O

Control Flow

Function & Procedure and Scope

Array & Pointers

Linux C Programming

Sorting

Struktur Data

Debugging Program C dengan GDB di Linux

GDB(GNU Project Debugger) merupakan tool yang dipakai untuk mengecek lebih dalam kode-kode program yang kita buat.
Biasanya kita mengecek error program dengan cara mengira-ngira dan menebak-nebak. Cara seperti itu sangat memakan energi dan waktu, apa lagi kalau program yang terdiri dari beberapa ribu bahkan diatas puluhan ribu baris kode. Nah, disinilah GDB akan membantu kita mempermudah proses men-debug sebuah program.

Kita akan memakai tool ini untuk debugging program binary search di bawah ini.
#include <stdio.h>

void binary_search(int data[], int length, int key)
{
    int start = 0;
    int end = length - 1;
    
    while (end >= start)
    {
        int current = (end + start) / 2;
        if (data[current] == key)
        {
            printf("%d ditemukan pada indeks ke-%d\n", key, current);
            return;
        }
        else if (data[current] > key)
        {
            end = current - 1;
        }
        else
        {
            start = current + 1;
        }
    }
    
    printf("Angka tidak ditemukan!\n");
    return;
}
 
int main()
{
    int num;
    printf("Masukkan banyaknya data: ");
    scanf("%d", &num);
    
    int data[num];
    for (int i = 0; i < num; i++)
    {
        printf("Angka ke-%d: ", i);
        scanf("%d", &data[i]);
    }
    
    int key;
    printf("Ketik angka yang ingin dicari: ");
    scanf("%d", &key);
    
    binary_search(data, num, key);
    
    return 0;
}
Simpan kode program tersebut dengan nama binary_search.c lalu di-compile dengan command make. Sebelum di-compile, edit dahulu pada file make yang telah dibuat terdahulu dengan menambahkan flag -ggdb3 sehingga makefile nya menjadi seperti ini.(Baca: Pemrograman C di Linux)
CC=clang

CFLAGS= -ggdb3 -std=c99 -Wall -Werror
Kemudian compile program tersebut dengan command make binary_search.

Kita mulai proses debugging program.
1. Pada terminal, ketik.
gdb ./binary_search
Sehingga akan muncul tampilan seperti ini.

2. Ketik break main agar gdb memulai mengecek program dari main()
Bisa dilihat pada tulisan line 33, karena main() dimulai pada baris ke-33, berarti gdb akan start pada baris ke-33.

3. Ketik run untuk menjalankan program, bisa juga dengan hanya mengetik r.
 GDB akan menampilkan kode program tersebut baris per baris, pada gambar terlihat kode program pada baris ke-33.

4. Ketik next untuk lanjut ke baris selanjutnya, bisa juga dengan hanya mengetik n.
GDB sampai pada baris ke-34 dimana terdapat scanf yang berfungsi menerima input dari user, sehingga muncul tampilan seperti di atas. Masukkan saja data sebanyak 5 data.

5. Karena kita sudah memasukkan nilai 5 pada variabel num, kita bisa mengecek nilai pada variabel tersebut dengan command.
print nama_variabel
Karena variabel tersebut bernama num, maka kita mengetik command print num sehingga akan muncul tampilan seperti ini.

6. Ketik next atau n sampai menyentuh baris yang terdapat fungsi binary_search(), ketik n untuk lanjut ke baris berikutnya, atau ketik step atau s untuk "memasukki" fungsi tersebut dan melihat kode-kode di dalamnya.
Bisa dilihat, gdb langsung "lompat" ke baris ke-5 dimana fungsi binary_search() dimulai, dan juga ditampilkan nilai-nilai yang dimasukkan ke dalam parameter-parameter pada fungsi tersebut. Parameter data berupa array sehingga yang tampil adalah alamat memory dari variabel array data tersebut, sedangkan parameter length bernilai 5 karena kita memasukkan variabel num di dalamnya, dan juga parameter key benilai 7 karena kita memasukkan variabel key di dalamnya.

7. Kita juga bisa melihat nilai-nilai variabel pada scope tertentu dengan command info locals. Misalnya ketika kita berada pada scope fungsi binary_search(), ketika kita mengetik info locals maka akan diperlihatkan nilai-nilai variabel yang ada pada scope fungsi tersebut. (Baca: Konsep Scope dalam Pemrograman C)
Nilai-nilai yang tampil adalah nilai variabel pada scope lokal di binary_search(), tetapi bukan pada scope while yang terdapat di dalamnya.


Nah, dari percobaan diatas kita sudah mengetahui fungsi-fungsi command ini.
run             Menjalankan program
next            Ke baris kode selanjutnya
print           Menampilkan nilai pada sebuah variabel
step            Melangkah masuk ke dalam sebuah fungsi/sub-program
info locals     Menampilkan nilai-nilai variabel pada scope tertentu

Sekian, semoga bermanfaat.

Command-line Arguments



Biasanya kita memberi nilai dari main() pada sebuah sub-program melalui parameter, tapi bisakah kita memberi nilai pada fungsi main() itu sendiri?
Disinilah gunanya Command-line Arguments, ialah argumen(nilai) yang kita beri melalui sistem operasi seperti Linux ke sebuah program.
Pertama-tama kita harus mengetahui dulu deklarasi parameter pada fungsi main(). Biasanya kita menulis seperti ini.
int main()
{

}
Untuk dapat menggunakan command-line arguments, kita mendeklarasikan fungsi main() seperti ini.
int main(int argc, char* argv[])
{

}
Contoh program sederhana.
#include <stdio.h>

int main(int argc, char* argv[])
{
   for (int i = 0; i < argc; i++)
   {
    printf("argv[%d]: %s\n", i, argv[i]);
   }

   return 0;
}

Program tersebut kita compile melalui terminal(ingat? Pemrograman C di Linux), lalu kemudian di-eksekusi seperti biasa dengan command ini.
./nama_program
Misalnya saya menamai file program tersebut cmdline.c, maka di-eksekusi seperti ini.
./cmdline
Dan outputnya akan seperti ini.

Misal saya beri nilai pada saat eksekusi melalui terminal seperti ini.
./cmdline azhary arliansyah
Maka outputnya akan seperti ini.

Bisa kita analisis, nilai variabel argc adalah jumlah kata yang kita ketik pada terminal(dalam hal ini 3, yaitu ./cmdline, azhary, arliansyah). Lalu kata(string) tersebut disimpan pada variabel array argv.

Sekian, semoga bermanfaat !

Pemrograman C di Linux

Hello readers,

Disini ane jelasin sedikit cara memprogram C di linux. Tools yang dipake yaitu.
1. Text Editor (disarankan pake gedit)
2. Terminal

Nah, sekarang coba kita buka text editor melalui terminal dengan format command seperti ini.

text_editor nama_file
 Contoh:

Kalo file yang bernama hello belum ada, maka akan dibuat file baru. Kalo udah ada, maka akan membuka file yang sudah ada tersebut. Dan jangan lupa ditambah .c dibelakang nama file kalo ingin memprogram dalam bahasa C.

Oke, dan sekarang di gedit, coba buat contoh program sederhana seperti biasa.

#include <stdio.h>

int main()
{
   printf("Hello world!");
   return 0;
}

Kemudian di-save, terus di-compile and run.... but wait, kok gak ada tombol compile-nya sih di gedit?
Gedit itu hanyalah text editor bukan IDE(Integrated Development Environment). So, gimana nge-compilenya ?
Buka lagi terminal, kemudian ketik.

gcc hello.c -o hello

Tekan enter, kemudian di-execute dengan mengetik

./hello

Voila! our first program in linux... 

Let us make another program!
Buka terminal, kemudian ketik.

gedit pengulangan.c
 Lalu buatlah program seperti ini.

#include <stdio.h>

int main()
{
  for (int i = 0; i < 5; i++)
  {
     printf("Hello world!\n");
  }
  return 0;
}


Klik save, kemudian ketik lagi seperti yang diatas namun kali ini kita pake operator &&(dan) untuk menggabung dua command seperti ini

gcc pengulangan.c -o pengulangan && ./pengulangan
 Dan akan tampil seperti ini.

Oops, error. pengulangan tipe for hanya bisa dipake dalam mode c99. Gimana cara ubah ke mode c99? cukup dengan menambah -std=c99 saat nge-compile seperti ini.

gcc -std=c99 -o pengulangan pengulangan.c && ./pengulangan

Begitulah cara compile and run program di linux. Tapi kan rempong kalo ngetik panjang panjang kayak gcc blablabla tiap kita nge-compile program.

Kita gak perlu kok ngetik panjang kayak gitu tiap nge-compile program. Command kayak gitu cukup kita "bungkus" di dalam sebuah Makefile.
Caranya seperti ini, pertama buka gedit dan ketik.

CC = clang

CFLAGS = -std=c99 -Wall -Werror

Save as dengan nama Makefile tanpa .c dibelakangnya. Taruh file tersebut di dalam folder yang sama dengan source code yang lo buat.
Jadi, kalo ingin nge-compile program kita cukup mengetik di terminal kayak gini.

make pengulangan
Kemudian ketik.
./pengulangan


Voila! compiling program jadi lebih mudah.

Memprogram tanpa IDE emang agak sulit, tapi itu melatih ketelitian elo dalam coding, sehingga dapat mengurangi syntax error. Lagi pula gak cuma kesalahan sintaks yang bakal elo alami, pada materi struktur data lo bakal sering mengalami logic error dan kesalahan manajemen memori. Di linux kita bisa pake tool bernama valgrind untuk mengecek dimana memory leak yang kita buat. Juga ada tool bernama GNU Project Debugger(GDB) yang bisa kita gunakan untuk mengecek lebih dalam letak kesalahan logika program kita, tanpa harus membuang waktu mencari error dengan cara menebak-nebak.

Cara gunainnya nanti akan ane share di lain waktu :D
So, stay tuned!!