Implementasi Hybrid Cryptosystem dengan Algoritma One Time Pad dan Algoritma Rabin Cryptosystem dalam Pengamanan Data Teks
LISTING PROGRAM 1.
Bahasa Python 1.1. Modulegate.py
import sys sys.path.append("C:\skrip") import pythonA def gerbang(fungsi): if(fungsi == "bangkitKunci"): from pythonA import bangkitkanKunci p, q, n = bangkitkanKunci() print(p, q, n) elif(fungsi == "cekKunci"): from pythonA import cekKunci hasil = cekKunci(b,c) print(hasil) elif(fungsi == "enkripsi"): from pythonA import programEnkripsi C = programEnkripsi(d, b) for i in range(len(C)): print(C[i], end = " ") elif(fungsi == "dek"): from pythonA import decryptCiphertext cetak = decryptCiphertext(d, b, c) for i in range(len(cetak)): print(cetak[i], end = " ") elif(fungsi == "dek2"): from pythonA import decryptCiphertext2 cetak = decryptCiphertext2(d, b, c) for i in range(len(cetak)): print(cetak[i], end = " ") elif(fungsi == "cari"): from pythonA import cariHitamDariPath hasil = cariHitamDariPath(d, b) for i in range(len(hasil)): print(hasil[i], end = '') if(i < len(hasil)-1): print(',', end = '') elif(fungsi == "embed"): from pythonA import jalankanSisip stroutput = jalankanSisip(d, e, b) print(stroutput) elif(fungsi == "ekstrak"): from pythonA import jalankanEkstrak stroutput = jalankanEkstrak(d) print(stroutput) global a a = str(sys.argv[1]) global b b = int(sys.argv[2]) global c c = int(sys.argv[3]) global d d = str(sys.argv[4]) global e e = str(sys.argv[5]) gerbang(a) 1.2.
ModulepythonA.py
import random, time class Timer(object): ''' timer starts with class initialisation ''' def __init__(self): self.t1= time.time() self.t2= time.time() def getElapsedlTime(self): # gets total elapsed from class initialsation self.delta=time.time()-self.t1 return '{0:.3f}'.format(self.delta) def getTimeDifference(self): # gets time elapsed from previous reading (for first reading this is equal to total time elapsed getElapsedlTime() self.delta=time.time()-self.t2 self.t2 = time.time() return '{0:.3f}'.format(self.delta) def differentRandom(n): x = [] for i in range(0, len(str(n))): a = random.randint(2,n-1) while a in x: a = random.randint(2,n-1) x.append(a) return x def toBin(x): return "{0:b}".format(x) def ntobin(n): return toBin(n-1) def modExpSAM(x, y, z): b = toBin(y) t = len(b) result = 1 for i in range(0, t): result = (result * result) % z if(b[i] == "1"): result = (result * x) % z return result def moduloEks(acak, y, bil): z = 1 for j in range (1, y + 1): z = (acak * z) % bil return z def fermatPrime(x): y = x - 1 # panjang digit untuk pengetesan iterasi = len(str(x)) * 2 if(iterasi < 3): iterasi = 3 for i in range (0, iterasi): acak = random.randint(1, y) if(moduloEks(acak, y, x) != 1): return False return True def isPrime(x): lowPrimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73 ,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,15 7,163,167,173,179,181,191,193,197,199,211,223,227,229,233,2 39,241,251,257,263,269,271,277,281,283,293,307,311,313,317, 331,337,347,349,353,359,367,373,379,383,389,397,401,409,419 ,421,431,433,439,443,449,457,461,463,467,479,487,491,499,50 3,509,521,523,541,547,557,563,569,571,577,587,593,599,601,6 07,613,617,619,631,641,643,647,653,659,661,673,677,683,691, 701,709,719,727,733,739,743,751,757,761,769,773,787,797,809 ,811,821,823,827,829,839,853,857,859,863,877,881,883,887,90 7,911,919,929,937,941,947,953,967,971,977,983,991,997] if x in lowPrimes: return True elif x & 1 != 0: return fermatPrime(x) return False def bangkitkanKunci(): syarat_tdk_terpenuhi = True while syarat_tdk_terpenuhi: p = random.randint(3,10000) if (p % 4 == 3) and isPrime(p): syarat_tdk_terpenuhi = False syarat_tdk_terpenuhi = True while syarat_tdk_terpenuhi: q = random.randint(3,10000) if (q != p) and (q % 4 == 3) and isPrime(q): syarat_tdk_terpenuhi = False n = p * q return p, q, n def cekKunci(key1, key2): if (key1 % 4 == 3) and isPrime(key1) and (key2 % 4 == 3) and isPrime(key2) and (key1 != key2): return "T" else: return "F"
def enkripsi(P, n): if P < n: C = modExpSAM(P,2,n) return C return False def encryptAll(P, n): C = [] for i in range(0, len(P)): C.append(enkripsi(ord(P[i]),n)) if C[i] == False: break; return C def programEnkripsi(plaintext, kunciPublik): measure=Timer() P = str(plaintext) n = int(kunciPublik) C = encryptAll(P, n) C.append(measure.getElapsedlTime()) return C def extEuclid(a,b):A, B, x, lastx, y, lasty = a, b, 1, 0, 0, 1 while (B > 0): hasilBagi = A//B sisaBagi = A - hasilBagi * B A, B = B, sisaBagi S = x - hasilBagi * lastx x, lastx = lastx, S T = y - hasilBagi * lasty y, lasty = lasty, T return A, x, y def CRT(mp, mq, p, q): n = p * q M1 = n // p M2 = n // q gcd, y1, y2 = extEuclid(M1,M2) return mp*M1*y1, mq*M2*y2, n def autoDekripsi(C, p, q): mp = modExpSAM(C, (p+1)//4, p) mq = modExpSAM(C, (q+1)//4, q) x, y, n = CRT(mp,mq,p,q) P1 = (x + y) % n P2 = (x - y) % n P3 = (-x + y) % n P4 = (-x - y) % n return min(P1, P2, P3, P4) def autoDekripsirabin(C, p, q): mp = modExpSAM(C, (p+1)//4, p) mq = modExpSAM(C, (q+1)//4, q) x, y, n = CRT(mp,mq,p,q)
P1 = (x + y) % n P2 = (x - y) % n P3 = (-x + y) % n P4 = (-x - y) % n return min(P1, P2, P3, P4), P1, P2, P3, P4 def convertListStringCToInt(C): hasil = [] c = C.split(',') for i in c: hasil.append(int(i)) return hasil def decryptCiphertext2(C, p, q): measure=Timer() C = convertListStringCToInt(C) P = [] for i in range(0, len(C)): minP = autoDekripsi(C[i], p , q) P.append(chr(minP)) stringP = ''.join(P) et = measure.getElapsedlTime() cetak = [] cetak.append(stringP) cetak.append(et) temp = tulisHasilDekripsi(stringP) return cetak def decryptCiphertext(C, p, q): measure=Timer() C = list(C) ordo = [] for i in range(len(C)): ordo.append(ord(C[i])) C = ordo P = [] for i in range(0, len(C)): minP = autoDekripsi(C[i], p , q) P.append(chr(minP)) stringP = ''.join(P) et = measure.getElapsedlTime() cetak = [] cetak.append(stringP) cetak.append(et) temp = tulisHasilDekripsi(stringP) return cetak class Convert: def toLI(self, string): temp = string.split(',') temp2 = [] for e in temp: temp2.append(int(e)) return temp2 def toSI(self, L): temp = "" for i in range(len(L)): temp += str(L[i]) if(i < len(L)-1): temp += ',' return temp def toDec(self, P): temp = [] for i in range(len(P)): temp.append(ord(P[i])) return temp def toASCII(self, string): string = self.toLI(string) temp = "" for e in string: temp += chr(e) return temp #hasil = isPrime(100) #print(hasil) 2.
Bahasa C# 2.1. Fungsi Pembangkit Kunci pada FormPembangkitKunci.cs
public void runPythonBangkitKunci(){ ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true; p.UseShellExecute = false; p.Arguments = "c:\\skrip\\gate.py "+ "bangkitKunci 0 0
'x' 'x'"; // start the python program with two parameters try{ using(Process exeProc = Process.Start(p)){
StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd(); string []r = output.Split(new char[]{'
'}); textBoxKunciP.Text = r[0].ToString(); textBoxKunciQ.Text = r[1].ToString(); textBoxKunciN.Text = r[2].ToString();
} } catch{
MessageBox.Show("Gagal melakukan pembangkit kunci.", "Kesalahan Proses Pembangkit Kunci", MessageBoxButtons.OK, MessageBoxIcon.Error);
} } void ButtonGenerateClick(object sender, EventArgs e) { if(!string.IsNullOrWhiteSpace(textBoxKunciP.Text) & !string.IsNullOrWhiteSpace(textBoxKunciQ.Text)){ if(MessageBox.Show("Kunci yang anda tulis sebelumnya akan terhapus. Yakin untuk melanjutkan?", "Peringatan: Pembangkitan Kunci", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK){ runPythonBangkitKunci();
} } else{ runPythonBangkitKunci();
} }
2.2.Fungsi Cek Kunci pada FormPembangkitKunci.cs
void ButtonCekKunciClick(object sender, EventArgs e){ if(string.IsNullOrWhiteSpace(textBoxKunciP.Text) | string.IsNullOrWhiteSpace(textBoxKunciQ.Text)){
MessageBox.Show("Pasangan kunci tidak boleh ada yang kosong.", "Kesalahan Kunci", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxKunciN.Text = ""; } else if(!string.IsNullOrWhiteSpace(textBoxKunciP.Text) &
!string.IsNullOrWhiteSpace(textBoxKunciQ.Text)){ string hasil = runPythonCekKunci(); if(String.Equals(hasil, "T")){ int a = int.Parse(textBoxKunciP.Text); int b = int.Parse(textBoxKunciQ.Text); int c = a*b; textBoxKunciN.Text = c.ToString();
} else{ MessageBox.Show("Kunci tidak memenuhi syarat.",
"Kesalahan Kunci", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxKunciN.Text = ""; }
} } public string runPythonCekKunci(){ string hasil; int kunci1 = int.Parse(textBoxKunciP.Text); int kunci2 = int.Parse(textBoxKunciQ.Text); ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true; p.UseShellExecute = false; p.Arguments = "c:\\skrip\\gate.py "+ "cekKunci " + kunci1 +
" " + kunci2 + " 'x' 'x'"; try{ using(Process exeProc = Process.Start(p)){
StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd(); string []r = output.Split(new char[]{' '}); hasil = r[0][0].ToString();
} } catch{
MessageBox.Show("Gagal dalam melakukan cek kunci.", "Kesalahan Cek Kunci", MessageBoxButtons.OK, MessageBoxIcon.Error); hasil = "";
} return hasil; }
2.3.Fungsi Enkrip Pesan
void Button1EnkripsiClick(object sender, EventArgse) {
if (string.IsNullOrWhiteSpace(textBox1plaintext.Text) | stri
ng.IsNullOrWhiteSpace(textBox1keyotp.Text)){ MessageBox.Show("Kunci OTP atau Pesan tidak boleh kosong.", "Kesalahan Dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error); }else{ textBox2chiphertext.Text=""; //ambilplainteks string plain=textBox1plaintext.Text; //ambilpanjangplainteks int panjangplain=textBox1plaintext.Text.Length; //ambilkunci string kunci=textBox1keyotp.Text; //ambilpanjangkunci
int pk=kunci.Length; string cipher=""; //cekpanjangkuncidgnplain kunciotp= ""; if(pk<panjangplain){
//contohkunci=abc //plain:farid
//kunciotp=abc kunciotp +=kunci; string tempplain=Regex.Replace(plain, @"\s+", ""); int pjgtempplain=tempplain.Length; for(int i = 0; i<(panjangplain-pjgtempplain);i++){ //kunciotp=abcfa tempplain+= (char)tempplain[i]; } //MessageBox.Show(tempplain); //proses menyamakan kunci == plain //perulangan sesuai kurangnya kunci for(int i = 0; i<(panjangplain-pk);i++){ //kunciotp=abcfa kunciotp+= (char)tempplain[i]; } }else{ kunciotp = kunci; } DateTime startTime = DateTime.Now; MessageBox.Show("panjang karakter : "+panjangplain.ToString()); //algoritma otp for(int i=0; i<panjangplain;i++){ cipher+=(char) (plain[i] + kunciotp[i]); } 2.4.
Program Enkripsi Kunci Pesan void Button1EnkripkeyClick(object sender, EventArgs e) {
//cek kunci if(string.IsNullOrWhiteSpace(textBoxkeyRabin.Text)){ MessageBox.Show("Kunci publik belum ada.", "Kesalahan
Enkripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);
} //cek plain else if(string.IsNullOrEmpty(textBox1keyotp.Text)){
MessageBox.Show("Tidak ada pesan (plaintext) yang terdeteksi.", "Kesalahan Enkripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);
} else{ //jika ada string cipherText = runPythonEnkripsi();
} textBox1cipherkey.Copy(); public string runPythonEnkripsi(){ string hasil; string hasil2;
//ambil kunci int n = int.Parse(textBoxkeyRabin.Text); //ambil pesan string plaintext =kunciotp; //ambil pnjang kunci int pjgPlaintext = kunciotp.Length;
// string pltxt1 = plaintext.Replace("\"","\\\""); int temporary = 0; ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true; p.UseShellExecute = false; // make sure we can read the output from stdout p.Arguments = "c:\\skrip\\gate.py "+ "enkripsi " + n + " " + temporary + " \"" + pltxt1 + "\" 'x'"; try{ using(Process exeProc = Process.Start(p)){
StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd(); string r = output; // get the parameter hasil = r.ToString(); hasil2 = hasil.Replace(" ",","); hasil2 = hasil2.Remove(hasil2.Length-1,1); string elapsedTime = hasil2.Split(',').Last(); hasil2 = hasil2.Remove((hasil2.Length - elapsedTime.Length), elapsedTime.Length); hasil2 = hasil2.Remove(hasil2.Length-1,1); if(hasil2 == "False"){
MessageBox.Show("Kunci publik tidak memenuhi syarat.", "Kesalahan Melakukan Enkripsi", MessageBoxButtons.OK, MessageBoxIcon.Error); hasil2 = "";
} else{ textBox1cipherkey.Text = hasil2.ToString();
//Untuk menampilkan ASCII try{ string kode = textBox1cipherkey.Text.ToString();
List<string> listHasilSplit = new List<string>(kode.Split(',')); List<Int32> ci = listHasilSplit.ConvertAll(x =>
Convert.ToInt32(x)); List<char> liChar = new List<char>(ci.ConvertAll(x =>
Convert.ToChar(x))); string charToString = string.Join("", liChar.ToArray()); kode = charToString;
} catch{ } //End Tampil ASCII MessageBox.Show("Berhasil melakukan enkripsi (" + elapsedTime + " detik)", "Informasi", MessageBoxButtons.OK, MessageBoxIcon.Information); }
}
2.5. Program dekripsi Kunci Pesan
void Button1dekripkeyotpClick(object sender, EventArgs e) { if(string.IsNullOrWhiteSpace(kp.Text)|string.IsNullOrWhiteSpace(kq
.Text)){ MessageBox.Show("Kunci private tidak boleh kosong.", "Kesalahan Dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);
} else if(string.IsNullOrEmpty(ctotp.Text)){ MessageBox.Show("Tidak ada ciphertext terdeteksi.", "Kesalahan Dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);
} else{ try{ string ciphertext = ctotp.Text.ToString(); string[] bufferS = new string[ctotp.Text.ToString().Length]; bufferS = ubahKeInt(); string result = ConvertStringArrayToStringJoin(bufferS);
List<string> listHasilSplit = new List<string>(ciphertext.Split(',')); List<Int32> ci = listHasilSplit.ConvertAll(x => Convert.ToInt32(x));
List<char> liChar = new List<char>(ci.ConvertAll(x => Convert.ToChar(x))); string charToString = string.Join("", liChar.ToArray()); ciphertext = charToString; string plaintext = runPythonDekripsi(ciphertext); } catch{ //MessageBox.Show("Ciphertext harus berupa angka yang dipisah dengan koma.", "Kesalahan melakukan dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error); string ciphertext = ctotp.Text.ToString(); string plaintext = runPythonDekripsi(ciphertext);
} } } public string ConvertStringArrayToStringJoin(string[] array){ string result = string.Join(",", array); return result;
} string[] ubahKeInt(){ string C = ctotp.Text.ToString(); char[] charArr = C.ToCharArray(); int val; string[] bufferS = new string[charArr.Length]; for(int i = 0; i < charArr.Length; i++){ val = Convert.ToInt32(charArr[i]); bufferS[i] = Convert.ToString(val);
StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd(); string r = output; // get the parameter hasil = r.ToString(); string[] parts = hasil.Split(' '); string elapsedTime = parts[parts.Length - 2]; hasil2 = hasil.Remove((hasil.Length
} return bufferS; } public string runPythonDekripsi(string strIntC){ string hasil; string hasil2; int kunciP = int.Parse(kp.Text); int kunciQ = int.Parse(kq.Text); ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true; p.UseShellExecute = false; // make sure we can read the output from stdout p.Arguments = "c:\\skrip\\gate.py "+ "dek " + kunciP + " " + kunciQ + " " + "\"" + strIntC + "\" 'x'"; // start the python program with two parameters try{ using(Process exeProc = Process.Start(p)){
- elapsedTime.Length), elapsedTime.Length); hasil2 = hasil2.Remove(hasil2.Length-1,1); hasil2 = hasil2.Remove(hasil2.Length-1,1); // menghilangkan spasi di akhir kalimat kotp.Text = hasil2.ToString(); int pjgPesanAsli = hasil2.Length; MessageBox.Show("Berhasil melakukan dekripsi (" + elapsedTime + " detik)", "Informasi", MessageBoxButtons.OK, MessageBoxIcon.Information);
} } catch{ //throw; strIntC = ctotp.Text.ToString(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true; p.UseShellExecute = false; // make sure we can read the output from stdout p.Arguments = "c:\\skrip\\gate.py "+ "dek2
" + kunciP + " " + kunciQ + " " + "\"" + strIntC + "\" 'x'"; // start the python program with two parameters try{ using(Process exeProc =
Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd(); string r = output; // get the parameter hasil = r.ToString(); string[] parts = hasil.Split('
'); string elapsedTime = parts[parts.Length - 2]; hasil2 = hasil.Remove((hasil.Length - elapsedTime.Length), elapsedTime.Length); hasil2 = hasil2.Remove(hasil2.Length-1,1); hasil2 = hasil2.Remove(hasil2.Length-1,1); // menghilangkan spasi di akhir kalimat kotp.Text = hasil2; int pjgPesanAsli = hasil2.Length; MessageBox.Show("Berhasil melakukan dekripsi (" + elapsedTime + " detik)", "Informasi",
MessageBoxButtons.OK, MessageBoxIcon.Information); }
} catch{ //throw; strIntC = kotp.Text.ToString(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true; p.UseShellExecute = false; // make sure we can read the output from stdout p.Arguments = "c:\\skrip\\gate.py "+
"dek2 " + kunciP + " " + kunciQ + " " + "\"" + strIntC + "\" 'x'"; // start the python program with two parameters try{ using(Process exeProc =
Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd(); string r = output; // get the parameter hasil = r.ToString(); string[] parts = hasil.Split(' '); string elapsedTime = parts[parts.Length - 2]; hasil2 = hasil.Remove((hasil.Length - elapsedTime.Length), elapsedTime.Length); hasil2 = hasil2.Remove(hasil2.Length-1,1); hasil2 = hasil2.Remove(hasil2.Length-1,1); // menghilangkan spasi di akhir kalimat kotp.Text = hasil2; int pjgPesanAsli = hasil2.Length;
MessageBox.Show("Berhasil melakukan dekripsi (" + elapsedTime + " detik)", "Informasi", MessageBoxButtons.OK, MessageBoxIcon.Information);
} } catch{
//throw;
MessageBox.Show("Kesalahan melakukan dekripsi.", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error); hasil2 = "";
} }
} return hasil2; } 2.6.
Perogram dekripsi pesan
void Button2dekripsiClick(object sender, EventArgs e) { if(string.IsNullOrWhiteSpace(textBox1cipher.Text) | string.IsNullOrWhiteSpace(textBox1cipherkey.Text)){
MessageBox.Show("Kunci OTP dan Pesan Cipher tidak boleh kosong.", "Kesalahan Dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);} else{ //ambil cipher string cipher=textBox1cipher.Text; //panjang cipher int panjang= textBox1cipher.Text.Length; //ambil kunci string kunci = kotp.Text; string pesan=""; DateTime waktuawal = DateTime.Now; //algoritma otp for(int i=0; i<panjang;i++){ pesan += (char)(cipher[i]-kunci[i]); //MessageBox.Show(pesan.ToString());
} MessageBox.Show("panjang : "+panjang.ToString());
MessageBox.Show("tes"); DateTime waktuakhir = DateTime.Now; /*MessageBox.Show("Time : " + elapsed.Hours.ToString("00") + ":" +elapsed.Minutes.ToString("00") + ":" + elapsed.Seconds.ToString("00") + "."
- elapsed.Milliseconds.ToString("000"));*/ pesanbox.Text=pesan; TimeSpan selisihwaktu = waktuakhir.Subtract(waktuawal);
MessageBox.Show("Time : "
- selisihwaktu.Hours.ToString()+" :"+selisihwaktu.Minutes.ToString()+" : " + selisihwaktu.Seconds.ToString()+" : "
- selisihwaktu.Milliseconds.ToString());}
CURRICULUM VITAE
Nama : Alfrid Iskandar Ramadhany Panggabean Alamat Sekarang : Jln. Umar Said No.1C Binjai Alamat Orang Tua : Jln. Umar Said No.1C Binjai Telp/ Hp : 087768644343 Email : Alfridiskandar@yahoo.com Riwayat Pendidikan 2010 : S-1 Ilmu Komputer Universitas Sumatera Utara, Medan
- – 2014 2007 : SMA Negeri 1, Binjai – 2010 2004 : SMP Negeri 2, Binjai – 2007 1998 : SD 020261, Binjai – 2004
Keahlian Bahasa : Indonesia, Inggris Bahasa Pemrograman : C#.NET, Python.
Database : Microsoft Access. Design : Photoshop, Corel Draw, Ilustrator Pengalaman Organisasi [2008
- – 2009] OSIS SMA Negeri 1 Binjai [2007
- – 2009] Paskibraka SMA Negeri 1 Binjai [2012
- – 2013] Anggota Kemahasiswaan IMILKOM 2012 - 2013 [2013
- – 2014] Kepala Bidang Kemahasiswaan IMILKOM 2013 – 2014
Pengalaman Kepanitiaan [2010] Anggota D okumentasi Seminar Teknologi Informasi “ The
Development Of Modern Operating System Technology” [2012] Ketua Bidang Dana dan Usaha PORSENI IMILKOM 2012 [2012] Ketua Bidang Acara PMB IMILKOM 2012