Implementasi Sistem Keamanan Data Menggunakan Steganografi Teknik Pemetaan Titik Hitam Dengan Pencarian Sekuensial Dan Rabin Cryptosystem

(1)

(2)

(3)

(4)

(5)

(6)

(7)

(8)

(9)

(10)

(11)

(12)

(13)

(14)

(15)

(16)

(17)

(18)

(19)

(20)

(21)

(22)

LISTING PROGRAM

1. Module gate.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


(23)

e = str(sys.argv[5]) gerbang(a)

2. Module pythonA.py

import sys, random, time, codecs from PIL import Image

import numpy as np

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 get_t(biner_n): t = 0

l_biner_n = int(len(biner_n))-1 for i in range(l_biner_n, -1, -1): if(biner_n[i] == "0"):

t += 1

if(biner_n[i] == "1"): break

return t

def get_u(biner_n, t):

bin_u = biner_n[0:int(len(biner_n))-t] u = int(bin_u, 2)


(24)

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 witness(a,u,n,t): x = []

x.append(modExpSAM(a, u, n)) for i in range(1, t+1):

x.append(modExpSAM(x[i-1],2,n))

if x[i] == 1 and x[i-1] != 1 and x[i-1] != n-1: return True if x[t] != 1:

return True return False

def MillerRabin(n): biner_n = ntobin(n) t = get_t(biner_n) u = get_u(biner_n, t) a = differentRandom(n) for i in range(len(a)):

if witness(a[i],u,n,t): 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,157,163,167,173,179,18 1,191,193,197,199,211,223,227,229,233,239,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,4 91,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,60 7,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,907,911,919,929,937,941,947,953,9 67,971,977,983,991,997]

if x in lowPrimes: return True elif x & 1 != 0:

return MillerRabin(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


(25)

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


(26)

return min(P1, P2, P3, P4)

def convertListStringCToInt(C): hasil = []

c = C.split(',') for i in c:

hasil.append(int(i)) return hasil

def tulisHasilDekripsi(P):

namaFile = "SUM - hasil dekripsi dari python berupa ASCII.txt" path = "C:\\Users\\hp\\Documents\\" + namaFile

try:

with codecs.open(path, "w", encoding = "utf-8") as file: file.write(P)

file.close() return True except:

return False

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

def bacaImage(lokasiFile): try:

listGambar = []

myimage = Image.open(lokasiFile).convert('RGB') pix = myimage.load()


(27)

height = myimage.size[1]

for i in range(width): for j in range(height):

listGambar.append(pix[i,j]) ndarray = np.array(myimage)

imgAsli = Image.fromarray(ndarray)

return listGambar, width, height, imgAsli except:

return False, False, False, False

def sequentialSearch(pixels, toleransiWarnaMax): htm = 0

for i in range(0, len(pixels)):

if(pixels[i][0] <= toleransiWarnaMax and pixels[i][1] <= toleransiWarnaMax and pixels[i][2] <= toleransiWarnaMax):

htm += 1 return htm

def cekRuangDanHitam(path, toleransi):

listGambar, width, height, imgAsli = bacaImage(path) if(listGambar == False): return False, False

if(toleransi < 15): toleransi = 15 elif(toleransi > 255): toleransi = 255

hitam = sequentialSearch(listGambar, toleransi) pr = listGambar[len(listGambar)-1][0]

pg = listGambar[len(listGambar)-1][1] pb = listGambar[len(listGambar)-1][2]

if(pr <= toleransi & pg <= toleransi & pb <= toleransi): hitam = hitam - 1

return (hitam * 3) // 4, hitam

def cariHitamDariPath(path, toleransiWarnaMax):

ruang, pjghitam = cekRuangDanHitam(path, toleransiWarnaMax) if(ruang and pjghitam == False): return False

hasil = []

hasil.append(ruang) hasil.append(pjghitam) return hasil

def fixingCiphertext(C): newC = []

for i in range(len(C)): strBiner = toBin(C[i]) if(len(strBiner) < 16):

selisih = 16 - len(strBiner) newStrBiner = strBiner

for x in range(selisih):

newStrBiner = '0' + newStrBiner newC.append(newStrBiner)

return newC

def parsingCiphertext(listC): newC, result = [], []

for i in range(len(listC)): if(len(listC[i]) == 16): elemen = []


(28)

elemen.append(listC[i][4:8]) elemen.append(listC[i][8:12]) elemen.append(listC[i][12:]) newC.append(elemen)

for i in range(len(newC)): for x in newC[i]: result.append(x) return result

def returnToInt(C): newC = []

for i in range(len(C)): desimal = int(C[i],2) newC.append(desimal) return newC

def splitIntCto4Int(C): ls = C.split(',') il = []

for i in ls:

il.append(int(i)) lbil = fixingCiphertext(il)

parse4lbil = parsingCiphertext(lbil) desimalparse = returnToInt(parse4lbil) return desimalparse

def fixLengthBeforeEmbed(C): while(len(C) % 3 != 0): C.insert(len(C), 0) index, color = 0, []

for i in range(len(C)//3):

color.append((C[index], C[index+1], C[index+2])) index += 3

return color

def filterGambar(listGambar): temp = []

for elemen in listGambar:

if(elemen == (254, 254, 254)): elemen = (255, 255, 255) temp.append(elemen)

return temp

def pemetaanHitam(pixels, toleransiWarnaMax): htm = []

for i in range(0, len(pixels)-1):

if(pixels[i][0] <= toleransiWarnaMax and pixels[i][1] <= toleransiWarnaMax and pixels[i][2] <= toleransiWarnaMax):

htm.append(i) return htm

def cekSyaratSebelumEmbed(listHitam, listWarnaC): if(len(listHitam) >= len(listWarnaC)):

return True return False

def transposeMatrix(M):

return [ [ row[i] for row in M ] for i in range(len(M[0])) ]


(29)

for i in range(len(warna)):

arrayGambar[indexHitam[i]] = warna[i]

if((len(warna)) < len(arrayGambar)):

arrayGambar[indexHitam[len(warna)-1] + 1] = (254,254,254)

stego = arrayGambar temp, stegoImg = [], []

for i in range(1, len(arrayGambar)+1): temp.append(arrayGambar[i-1]) if(i % tinggi == 0):

stegoImg.append(temp) temp = []

stegoImg = transposeMatrix(stegoImg) stegoImg = np.array(stegoImg, "uint8") stegoImg = Image.fromarray(stegoImg) return stego, stegoImg

def simpan(stegoImg):

return stegoImg.save("C:/Users/hp/Documents/stegoimgpy.bmp", "BMP")

def getRGB(cariCipher): r, g, b = [], [], [] for color in cariCipher: r.append(color[0]) g.append(color[1]) b.append(color[2]) return r, g, b

def printRGBinStringAndReturnString(r,g,b): temp = ""

for i in range(len(r)): temp += str(r[i]) if(i != len(r)-1): temp += "," temp += "/"

for i in range(len(g)): temp += str(g[i]) if(i != len(g)-1): temp += "," temp += "/"

for i in range(len(b)): temp += str(b[i]) if(i != len(b)-1): temp += "," return temp

def jalankanSisip(intCiphertext, filename, toleransiWarnaMax): measure=Timer()

intCiphertext = list(intCiphertext) ordo = []

for i in range(len(intCiphertext)): ordo.append(ord(intCiphertext[i])) temp = ""

for i in range(len(ordo)): temp += str(ordo[i]) if(i != len(ordo)-1): temp += ","


(30)

listCi = splitIntCto4Int(intCiphertext) listWarna = fixLengthBeforeEmbed(listCi)

listGambar, lebar, tinggi, imgAsli = bacaImage(filename) listGambarFilter = filterGambar(listGambar)

hitam = pemetaanHitam(listGambarFilter, toleransiWarnaMax)

syaratEmbed = cekSyaratSebelumEmbed(hitam, listWarna) if(syaratEmbed):

stegoArray, stegoImg = sisip(listGambarFilter, hitam, tinggi, listWarna)

simpan(stegoImg)

r, g, b = getRGB(stegoArray)

stroutput = printRGBinStringAndReturnString(r,g,b) et = measure.getElapsedlTime()

stroutput += " " + str(et) return stroutput

et = measure.getElapsedlTime() stroutput = "False " + str(et) return stroutput

def cariTitikPutih(listGambarEkstrak): putih = 0

for e in listGambarEkstrak:

if((e[0] == 254) and (e[1] == 254) and (e[2] == 254)): putih += 1

if(putih != 1): return False

elif((putih == 1) and (listGambarEkstrak[0] != (254, 254, 254))): return True

return False

def cariCiphertext(listGambar): listC = []

for e in listGambar:

if((e[0] == 254) and (e[1] == 254) and (e[2] == 254)): break

if((e[0] <= 15) and (e[1] <= 15) and (e[2] <= 15)): listC.append(e)

return listC

def convertColorEkstrakToListInt(CE): il = []

for i in CE: for e in i:

il.append(int(e)) return il

def removeLastZeroOutofRange(liCE): if(len(liCE) % 4 != 0):

for i in range(len(liCE) % 4): idxAkhir = len(liCE) - 1 liCE.pop(idxAkhir)

return liCE

def ambilEmpat(L): i = 0


(31)

for iterasi in range(len(L) // 4):

hasil.append((L[i], L[i+1], L[i+2], L[i+3])) i += 4

return hasil

def dariEmpatJadiBiner(L): hasil, binerfix = [], [] for e in L:

for i in e:

biner = toBin(i)

while(len(biner) < 4): biner = '0' + biner binerfix.append(biner) idx = 0

for i in range(len(binerfix) // 4):

hasil.append(binerfix[idx] + binerfix[idx+1] + binerfix[idx+2] + binerfix[idx+3])

idx += 4 return hasil

def biner16keInt(L): hasil = []

for e in L:

hasil.append(int(e, 2)) return hasil

def cetakstringint(L): hasil = ""

for i in range(len(L)): hasil += str(L[i]) if( i != len(L)-1): hasil += "," return hasil

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 = ""


(32)

for e in string: temp += chr(e) return temp

def tulisHasilEkstrakASCII(C): gagal = False

try:

C = Convert().toLI(C) temp = []

for e in C: try:

temp.append(chr(e)) except:

gagal = True continue C = temp

temp = ""

for i in range(len(C)): temp += str(C[i]) C = temp

except: C = C

namaFile = "SUM - hasil dekripsi dari python berupa ASCII.txt" path = "C:\\Users\\hp\\Documents\\" + namaFile

try:

with codecs.open(path, "w", encoding = "utf-8") as file: file.write(C) file.close() return True except: return False def jalankanEkstrak(path): measure=Timer()

listGambarEkstrak, width, height, imgAsli= bacaImage(path) if(cariTitikPutih(listGambarEkstrak)):

cariCipher = cariCiphertext(listGambarEkstrak) liCE = convertColorEkstrakToListInt(cariCipher) liCE = removeLastZeroOutofRange(liCE)

liCE = ambilEmpat(liCE)

liCE = dariEmpatJadiBiner(liCE) liCE = biner16keInt(liCE)

stroutput = cetakstringint(liCE)

temp = tulisHasilEkstrakASCII(stroutput) et = measure.getElapsedlTime()

stroutput += "/" + str(et) return stroutput

et = measure.getElapsedlTime() stroutput = "False/" + str(et) return stroutput

3. Fungsi Pembangkit Kunci pada FormPembangkitKunci.cs

public void runPythonBangkitKunci(){

ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;


(33)

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(); } }

4. 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 = ""; }


(34)

}

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; }

5. Fungsi Enkripsi pada FormEnkripEmbed.cs

void ButtonEnkripsiClick(object sender, EventArgs e){

if(string.IsNullOrWhiteSpace(textBoxKunciPublik.Text)){ MessageBox.Show("Kunci publik belum ada.", "Kesalahan Enkripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

else if(string.IsNullOrEmpty(textBoxPesan.Text)){

MessageBox.Show("Tidak ada pesan (plaintext) yang terdeteksi.", "Kesalahan Enkripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);

} else{

string cipherText = runPythonEnkripsi(); }

}

public string runPythonEnkripsi(){ string hasil;

string hasil2;

int n = int.Parse(textBoxKunciPublik.Text); string plaintext = textBoxPesan.Text.ToString(); int pjgPlaintext = textBoxPesan.Text.Length; string pltxt1 = plaintext.Replace("\"","\\\""); int temporary = 0;

ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;

p.UseShellExecute = false;

p.Arguments = "c:\\skrip\\gate.py "+ "enkripsi " + n + " " + temporary + " \"" + pltxt1 + "\" 'x'";


(35)

using(Process exeProc = Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd();

string r = output; hasil = r.ToString();

hasil2 = hasil.Replace(" ",",");

hasil2 = hasil2.Remove(hasil2.Length-1,1); string elapsedTime = hasil2.Split(',').Last(); textBoxWaktuProses.Text = elapsedTime;

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{

textBoxCiphertext.Text = hasil2.ToString(); try{

string kode = textBoxCiphertext.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; textBoxCipherASCII.Text = kode.ToString(); } catch{ textBoxCipherASCII.Text = hasil2.ToString(); }

MessageBox.Show("Berhasil melakukan enkripsi (" + elapsedTime + " detik)", "Informasi", MessageBoxButtons.OK, MessageBoxIcon.Information);

} }

} catch{

MessageBox.Show("Kesalahan melakukan enkripsi", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error);

hasil2 = ""; }

return hasil2; }

6. Fungsi Cari Titik Hitam pada FormEnkripEmbed.cs

void ButtonCariClick(object sender, EventArgs e){

if(string.IsNullOrEmpty(textBoxPathBrowseImage.Text)){ MessageBox.Show("Gambar belum dipilih.", "Kesalahan Membaca Titik Hitam", MessageBoxButtons.OK, MessageBoxIcon.Error);


(36)

else{

string path = textBoxPathBrowseImage.Text.ToString(); if(string.IsNullOrEmpty(textBoxToleransiMax.Text)){

MessageBox.Show("Batas toleransi maksimum dari nilai warna hitam belum ditentukan.", "Kesalahan Membaca Titik Hitam", MessageBoxButtons.OK, MessageBoxIcon.Error);

} else{

int toleransi = int.Parse(textBoxToleransiMax.Text);

if((toleransi < 15) || (toleransi > 255)){ MessageBox.Show("Toleransi melebihi nilai maksimum.\nNilai harus diantara 15 sampai 255", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error);

textBoxToleransiMax.Text = ""; textBoxToleransiMax.SelectAll(); } else{runPythonCekHitamFromPath(path, toleransi);} } } }

void runPythonCekHitamFromPath(string path, int toleransi){ string hasil;

int temporary = 0;

ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;

p.UseShellExecute = false;

p.Arguments = "c:\\skrip\\gate.py "+ "cari " + toleransi + " " + temporary + " \"" + path + "\" 'x'";

try{

using(Process exeProc = Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd();

string r = output; hasil = r.ToString();

string[] parts = hasil.Split(','); string hitam = parts[1];

string ruang = parts[0];

textBoxJumlahTitikHitam.Text = hitam;

MessageBox.Show("Jumlah karakter dari pesan rahasia yang dapat disisip sebanyak " + ruang + " karakter", "Informasi

Jumlah Karakter", MessageBoxButtons.OK, MessageBoxIcon.Information); try{

int pjgc = 0; try{

string C = textBoxCiphertext.Text.ToString();

List<string> listHasilSplit = new List<string>(C.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());

pjgc = charToString.Length; }


(37)

finally{

int pjgruanghtm = int.Parse(ruang); if(pjgruanghtm < pjgc){

MessageBox.Show("Penyisipan tidak dapat dilakukan.\nJumlah karakter pesan rahasia melebihi jumlah yang dapat disisip.", "Informasi", MessageBoxButtons.OK,

MessageBoxIcon.Hand); } } } catch{ //none } } } catch{

MessageBox.Show("Kesalahan dalam mencari titik hitam.", "Kesalahan Pencarian Titik Hitam", MessageBoxButtons.OK,

MessageBoxIcon.Error); }

}

7. Fungsi Embed pada FormEnkripEmbed.cs

void ButtonEmbedClick(object sender, EventArgs e){

if(!string.IsNullOrEmpty(textBoxCiphertext.Text)){

string result = textBoxCiphertext.Text.ToString(); try{

List<string> listHasilSplit = new List<string>(result.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());

result = charToString; }

catch{//None}

if(string.IsNullOrEmpty(textBoxPathBrowseImage.Text)){ MessageBox.Show("Cover Image belum dipilih.", "Kesalahan Penyisipan (Embed)", MessageBoxButtons.OK,

MessageBoxIcon.Error); }

else if(string.IsNullOrEmpty(textBoxToleransiMax.Text)){ MessageBox.Show("Batas toleransi maksimum dari nilai warna hitam belum ditentukan.", "Kesalahan Penyisipan (Embed)", MessageBoxButtons.OK, MessageBoxIcon.Error);

} else{

string path =

textBoxPathBrowseImage.Text.ToString(); string cipher = result; int maxTolerance =

int.Parse(textBoxToleransiMax.Text.ToString());

if((maxTolerance < 15) || (maxTolerance > 255)){ MessageBox.Show("Toleransi melebihi nilai maksimum.\nNilai harus diantara 15 sampai 255", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error);


(38)

textBoxToleransiMax.SelectAll(); }

else{runPyEmbed(cipher, path, maxTolerance);} }

}

else{MessageBox.Show("Tidak ada ciphertext yang terdeteksi.", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error);}

}

void runPyEmbed(string cipher, string path, int maxTolerance){ string hasil;

int temporary = 0;

string jikapltxt = cipher.Replace("\"","\\\""); cipher = jikapltxt;

ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;

p.UseShellExecute = false;

p.Arguments = "c:\\skrip\\gate.py "+ "embed " + maxTolerance + " " + temporary + " \"" + cipher + "\"" + " \"" + path + "\"";

try{

using(Process exeProc = Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd();

string r = output; hasil = r.ToString();

List<string> listHasilSplit = new List<string>(hasil.Split(' '));

if(listHasilSplit[0] == "False"){

MessageBox.Show("Jumlah titik hitam tidak cukup untuk menyembunyikan warna ciphertext.", "Kesalahan: Penyisipan Tidak Dapat Dilakukan", MessageBoxButtons.OK, MessageBoxIcon.Error);

} else{

textBoxWaktuProsesStegano.Text = listHasilSplit[1];

List<string> listSplit = new List<string>(listHasilSplit[0].Split('/'));

List<string> tempR = new List<string>(listSplit[0].Split(','));

List<string> tempG = new List<string>(listSplit[1].Split(','));

List<string> tempB = new List<string>(listSplit[2].Split(','));

List<int> R = tempR.ConvertAll(x => int.Parse(x));

List<int> G = tempG.ConvertAll(x => int.Parse(x));

List<int> B = tempB.ConvertAll(x => int.Parse(x));

int w =

int.Parse(textBoxWCoverImage.Text.ToString()); int h =

int.Parse(textBoxHCoverImage.Text.ToString()); int dim = w * h;

Bitmap bmp = new Bitmap(w, h); int idx = 0;

for(int i = 0; i < w; i++){


(39)

bmp.SetPixel(i,j,Color.FromArgb(255, R[idx], G[idx], B[idx])); idx++;

} }

pictureBoxStegoImage.Image = bmp; }

} }

catch{MessageBox.Show("Kesalahan melakukan penyisipan.\nCoba tutup aplikasi dan lakukan kembali.", "Kesalahan",

MessageBoxButtons.OK, MessageBoxIcon.Error);} }

8. Fungsi Ekstrak pada FormEkstrakDekrip.cs

void ButtonEkstrakClick(object sender, EventArgs e){ if(pictureBoxStegoImage.Image != null){

string path = textBoxPathStegoImage.Text.ToString(); runPyEkstrak(path);

}

else{MessageBox.Show("Stego-image belum dipilih.", "Kesalahan Ekstrak Gambar", MessageBoxButtons.OK, MessageBoxIcon.Error);} }

void runPyEkstrak(string path){ string hasil;

string hasil2;

ProcessStartInfo p = new ProcessStartInfo(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;

p.UseShellExecute = false;

p.Arguments = "c:\\skrip\\gate.py "+ "ekstrak 15 0 \"" + path + "\"" + " x";

try{

using(Process exeProc = Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd();

string r = output; hasil = r.ToString();

List<string> listHasilSplit = new List<string>(hasil.Split('/'));

textBoxWaktuProsesEkstrak.Text = listHasilSplit[1]; hasil2 = listHasilSplit[0];

if(hasil2 == "False"){

MessageBox.Show("Tidak ada pesan rahasia di dalam gambar.", "Hasil Ekstrak Tidak Ada", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

textBoxCiphertext.Text = ""; }

else{

textBoxCiphertext.Text = listHasilSplit[0]; string[] stringSeparators = new

string[]{","};

string[] result; result =

listHasilSplit[0].Split(stringSeparators, StringSplitOptions.None); char[] buffer = new char[result.Length]; Int32 temp;


(40)

temp = Convert.ToInt32(result[i]); buffer[i] = Convert.ToChar(temp); }

string charToString = new string(buffer); textBoxPesanAsli.Text = charToString; }

} }

catch{MessageBox.Show("Kesalahan melakukan ekstrak", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error);} }

9. Fungsi Dekripsi pada FormEkstrakDekrip.cs

void ButtonDekripsiClick(object sender, EventArgs e){ if(string.IsNullOrWhiteSpace(textBoxKunciP.Text) | string.IsNullOrWhiteSpace(textBoxKunciQ.Text)){

MessageBox.Show("Kunci private tidak boleh kosong.", "Kesalahan Dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

else if(string.IsNullOrEmpty(textBoxCiphertext.Text)){ MessageBox.Show("Tidak ada ciphertext terdeteksi.", "Kesalahan Dekripsi", MessageBoxButtons.OK, MessageBoxIcon.Error);

} else{

try{

string ciphertext = textBoxCiphertext.Text.ToString();

string[] bufferS = new

string[textBoxCiphertext.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{

string ciphertext = textBoxCiphertext.Text.ToString();

string plaintext = runPythonDekripsi(ciphertext); }

} }

public string ConvertStringArrayToStringJoin(string[] array){ string result = string.Join(",", array);

return result; }

string[] ubahKeInt(){


(41)

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); }

return bufferS; }

public string runPythonDekripsi(string strIntC){ string hasil;

string hasil2;

int kunciP = int.Parse(textBoxKunciP.Text); int kunciQ = 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 "+ "dek " + kunciP + " " + kunciQ + " " + "\"" + strIntC + "\" 'x'";

try{

using(Process exeProc = Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd();

string r = output; hasil = r.ToString();

string[] parts = hasil.Split(' ');

string elapsedTime = parts[parts.Length - 2]; textBoxWaktuProsesDekripsi.Text = elapsedTime; hasil2 = hasil.Remove((hasil.Length -

elapsedTime.Length), elapsedTime.Length);

hasil2 = hasil2.Remove(hasil2.Length-1,1); hasil2 = hasil2.Remove(hasil2.Length-1,1); textBoxPesanAsli.Text = hasil2;

int pjgPesanAsli = hasil2.Length;

textBoxPjgPesanAsli.Text = pjgPesanAsli.ToString(); MessageBox.Show("Berhasil melakukan dekripsi (" + elapsedTime + " detik)", "Informasi", MessageBoxButtons.OK,

MessageBoxIcon.Information); }

} catch{

strIntC = textBoxCiphertext.Text.ToString(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;

p.UseShellExecute = false;

p.Arguments = "c:\\skrip\\gate.py "+ "dek2 " + kunciP + " " + kunciQ + " " + "\"" + strIntC + "\" 'x'";

try{

using(Process exeProc = Process.Start(p)){ StreamReader s = exeProc.StandardOutput; String output = s.ReadToEnd();

string r = output; hasil = r.ToString();

string[] parts = hasil.Split(' ');

string elapsedTime = parts[parts.Length - 2]; textBoxWaktuProsesDekripsi.Text =


(42)

hasil2 = hasil.Remove((hasil.Length - elapsedTime.Length), elapsedTime.Length);

hasil2 = hasil2.Remove(hasil2.Length-1,1); hasil2 = hasil2.Remove(hasil2.Length-1,1); textBoxPesanAsli.Text = hasil2;

int pjgPesanAsli = hasil2.Length; textBoxPjgPesanAsli.Text =

pjgPesanAsli.ToString();

MessageBox.Show("Berhasil melakukan dekripsi (" + elapsedTime + " detik)", "Informasi", MessageBoxButtons.OK, MessageBoxIcon.Information);

} }

catch{

strIntC = textBoxPesanAsli.Text.ToString(); p.FileName = "c:\\Python33\\python.exe"; p.RedirectStandardOutput = true;

p.UseShellExecute = false;

p.Arguments = "c:\\skrip\\gate.py "+ "dek2 " + kunciP + " " + kunciQ + " " + "\"" + strIntC + "\" 'x'";

try{

using(Process exeProc = Process.Start(p)){ StreamReader s =

exeProc.StandardOutput;

String output = s.ReadToEnd(); string r = output;

hasil = r.ToString();

string[] parts = hasil.Split(' '); string elapsedTime = parts[parts.Length - 2];

textBoxWaktuProsesDekripsi.Text = elapsedTime;

hasil2 = hasil.Remove((hasil.Length - elapsedTime.Length), elapsedTime.Length);

hasil2 = hasil2.Remove(hasil2.Length-1,1);

hasil2 = hasil2.Remove(hasil2.Length-1,1);

textBoxPesanAsli.Text = hasil2; int pjgPesanAsli = hasil2.Length; textBoxPjgPesanAsli.Text =

pjgPesanAsli.ToString();

MessageBox.Show("Berhasil melakukan dekripsi (" + elapsedTime + " detik)", "Informasi",

MessageBoxButtons.OK, MessageBoxIcon.Information); }

} catch{

MessageBox.Show("Kesalahan melakukan

dekripsi.", "Kesalahan", MessageBoxButtons.OK, MessageBoxIcon.Error); hasil2 = "";

} }

}

return hasil2; }


(43)

D

AFTAR

R

IWAYAT

H

IDUP

CURRICULUM VITAE

I. DATA PRIBADI /Personal Identification

Nama Lengkap : Aulia Akbar Harahap Tempat / Tgl. Lahir : Medan / 15 April 1993 Jenis Kelamin : Laki – laki

Agama : Islam

Kebangsaan : Indonesia

Alamat : Jalan Karya Pembangunan, Komplek BLPP No. 22 Gedung Johor, Medan, Sumatera Utara, Indonesia 20143

Telepon : +62617865990 / +6283198507519 Moto Hidup : Berusaha dan Bersyukur

Tinggi / Berat : 178 cm / 86 kg

Email : auliaakbarharahaap@gmail.com II. KESEHATAN /Health

Tidak memiliki cacat fisik maupun mental dan tidak memiliki penyakit bawaan. III. KEMAMPUAN / Capabilities

Bahasa : Bahasa Indonesia, Bahasa Inggris Bahasa Pemrograman : C#, Python, PHP, JavaScript, C++

Database : MySQL

Lainnya : HTML, CSS, Photoshop, Ms. Office, Adobe Flash IV. PENDIDIKAN FORMAL / Formal Education

 [ 2010 – 2014 ]

Implementasi Sistem Keamanan Data Menggunakan Steganografi Teknik Pemetaan Titik Hitam dengan Pencarian Sekuensial dan Rabin Cryptosystem

S1 Ilmu Komputer, Fakultas Ilmu Komputer dan Teknologi Informasi Universitas Sumatera Utara

 [ 2007 – 2010 ]

SMA Negeri 2 Medan  [ 2005 – 2007 ]

SMP Swasta Harapan Mandiri, Medan  [ 1998 – 2004 ]

SD Angkasa I Lanud Medan  [ 1997 – 1998 ]


(44)

V. PENDIDIKAN NON-FORMAL / Informal Education  [ 2005 – 2006 ]

Ta’limul Qur’an Lil Aulad (TQA) Al- Amin, Medan  [ 2008 – 2010 ]

Ganesha Operation, Medan. VI. PRESTASI / Achievements

1) Juara II Kompetisi Desain Grafis, ArTechno Festival 2011 Universitas Sumatera Utara [2011] 2) Peringkat II Tingkat TQAL, Perguruan Islam Al-Amin [2006]

VII. PENGALAMAN KERJA / Working Experience

1) Desainer Grafis dan Wakil Sekretaris di CV Dhuo Creative, Medan [2011 – 2012]

2) Asisten Laboratorium di Ilmu Komputer Laboratory Center Fasilkom-TI USU, Medan [2011-2012]

3) Kerja Lepas (freelancer) di Focus, Active and Network Coorporation (FAN), Medan [2013] VIII. PENGALAMAN BERBICARA / Speaking Experience

1) Pemateri di Pelatihan Kesekretariatan, UKMI Al-Khuwarizmi Fasilkom-TI USU, Medan [2013]

2) Pemateri Desain Web di Penerimaan Mahasiswa Baru, IMILKOM, Medan [2013]

3) Pemateri Photo Manipulation di Pelatihan Spesifikasi Dunia Ilmu Komputer (IKLC Mengabdi), Ilmu Komputer Laboratory Center Fasilkom-TI USU, Medan-Perbaungan [2013] 4) Pemateri di Pelatihan Kesekretariatan dan Teknik Persidangan, UKMI Al-Khuwarizmi

Fasilkom-TI USU dan IMILKOM, Medan [2013]

5) Tutor Pelatihan Blog di Academy Syiar Media, Departemen Komunikasi Dakwah UKMI Ad-Dakwah USU, Medan [2012]

6) Tutor Pelatihan Blog di Ad-Dakwah Bloggership Camp, Departemen Komunikasi Dakwah UKMI Ad-Dakwah USU, Medan [2012]

7) Instruktur di Pesantren Kilat Ramadhan, BKM Al-Farabi SMAN 2 Medan [2011] IX. PENGALAMAN PERTEMUAN DAN DELEGASI / Conference and Delegation Experience

1) Delegasi studi banding dari USU ke Fakulti Sains Komputer dan Teknologi Maklumat, Universiti Putera Malaysia [2011]

X. PELATIHAN / Trainings & Workshop

1) Peserta Pelatihan Jurnalistik Metro TV on Campus, Universitas Sumatera Utara, Medan [2013]

2) Peserta Workshop Digital Paperless Publication: ALAMAGZ (Al-Khuwarizmi Magazine), UKMI Al-Khuwarizmi Fasilkom-TI USU, Medan [2011]

3) Peserta ESQ Basic Training, Training ESQ Inhouse Basic Mahasiswa Angkatan 002, The ESQ Way 165, Medan [2011]

4) Peserta Workshop Design Talent: Desain Poster, CV Dhuo Creative, Medan [2011]

5) Peserta Workshop Konfigurasi Access Point & Wireless Security, PT Telkom Indonesia, Tbk Regional I Sumatera, Medan [2011]

6) Peserta Training Pengurus, BKM Al-Khuwarizmi, Medan [2011]

7) Peserta Training Emotional Spiritual Management, UKMI Al-Falak FMIPA USU, Medan [2010]

8) Peserta Workshop Teknik Hacking, IMILKOM Fair 2010, Medan [2010]

9) Peserta Workshop Graphic Design: Unlimited, IMILKOM Fair 2010, Medan [2010] 10) Peserta Workshop Web Development, IMILKOM Fair 2010, Medan [2010]


(45)

12) Peserta Training Islam Ceria dan Kreatif, BKM Al-Khuwarizmi, Medan [2010] 13) Peserta Inagurasi, IMILKOM, Medan [2010]

14) Peserta Ramadhan Student Expo, Muslim Youth Club, Medan [2008] 15) Peserta Kemah Desember, PMR 001 SMAN 2 Medan [2007]

16) Peserta Pesantren Kilat Ramadhan, BKM Al-Farabi SMAN 2 Medan [2007] XI. SEMINAR / Seminars

1) Peserta Seminar Nasional: “Pencaplokan Budaya”, Kongres Nasional Ikatan Lembaga Penalaran dan Penelitian Mahasiswa Indonesia IV, Medan [2013]

2) Peserta Seminar Teknologi Informasi: “The Future Augmented Reality: Research and Implementation”, Universitas Sumatera Utara, Medan [2012]

3) Peserta Seminar Teknologi Informasi: “Android The New Trend in Modern Operating System”, Universitas Sumatera Utara, Medan [2010]

XII. PENGALAMAN ORGANISASI / Organizational Experiences

1) Ketua Relawan TIK (Indonesian ICT Volunteers) Komisariat USU [2013 – 2014] 2) Anggota Biro Kesekretariatan IMILKOM [2013 – 2014]

3) Koordinator Divisi Administrasi dan Pengarsipan KPU Ilmu Komputer USU [2012 – 2013] 4) Sekretaris Umum di UKMI Al-Khuwarizmi Fasilkom-TI USU [2012 – 2013]

5) Anggota Pembinaan Anggota di BKM Al-Khuwarizmi USU [2011] 6) Anggota Majelis Perwakilan Kelas di SMAN 2 Medan [2008 – 2009] 7) Anggota PMR 001 WIRA A di SMAN 2 Medan [2006 – 2007] 8) Anggota BKM Al-Farabi SMAN 2 Medan [2007 – 2009] XIII. PENGALAMAN KEPANITIAAN / Committee Experiences

1) Panitia Pelaksana pada Pelatihan Sistem Informasi Geografis di S1 Ilmu Komputer USU [2013]

2) Anggota Acara di ArTechno 2013 [2013]

3) Panitia Pelaksana pada Pelatihan Sistem Informasi Geografis di S1 Ilmu Komputer USU [2012]

4) Anggota Publikasi dan Dokumentasi di PORSENI IMILKOM [2012]

5) Anggota Acara di Penerimaan Mahasiswa Baru S1 Ilmu Komputer USU [2012] 6) Anggota Publikasi dan Dokumentasi di ArTechno 2012 [2012]

7) Panitia Penyuluhan Internet Sehat di Program Kreativitas Mahasiswa [2012] 8) Bendahara Umum di Bakti Sosial BKM Al-Khuwarizmi USU [2011]

9) Anggota Publikasi dan Dokumentasi di Ramadhan Expo 1432 H (Muslim Youth Club) [2011] 10) Ketua Panitia Seminar Teknologi Informasi The Development of Modern Operating System

Technology: “Android The New Trend in Modern Operating System” [2011] XIV. LAINNYA / Others

1) Relawan pada Penyuluhan Pengenalan Internet Sehat (Pengabdian Masyarakat) [2012] 2) Penerima Beasiswa Peningkatan Prestasi Akademik di FMIPA USU [2011 – 2012] 3) Peserta Lomba pada “Problem Solving” IMILKOM Contest [2012]

4) Peserta Lomba Poster Ilmiah pada Pameran Ilmiah dan Kreatifitas Mahasiswa [2012] 5) Penerima Sertifikat Kepengurusan BKM Al-Farabi SMAN 2 Medan sebagai Anggota Bina

Usaha Periode 2009 – 2010


(46)

DAFTAR PUSTAKA

Aditya, Y., Pratama, A. & Nurlifa, A. 2010. Studi pustaka untuk steganografi dengan beberapa metode. Prosiding Seminar Nasional Aplikasi Teknologi Informasi 2010 (SNATI 2010), pp. G-32 – G35.

Ambler, S. W. 2005. The Elements of UML™ 2.0 Style. Cambridge University Press: Cambridge.

Ariyus, D. 2008. Pengantar Ilmu Kriptografi: Teori, analisis dan implementasi. ANDI: Yogyakarta.

Cormen, T. H., Leiserson, C. E., Rivest, R. L. & Stein, C. 2009. Introduction to Algorithms. 3rd Edition. The MIT Press: Cambridge.

Fauzana, 2013. Analisis dan perancangan sistem autentikasi pengguna pada web menggunakan metode multiple-key RSA. Skripsi. Universitas Sumatera Utara. Galbraith, S. D. 2012. Mathematics of Public Key Cryptography. Cambridge University

Press: Cambridge.

Gaspersz, Vincent. 1997. Manajemen Kualitas: Penerapan konsep-konsep kualitas dalam manajemen bisnis total. Gramedia Pustaka Utama: Jakarta.

Hermawati, F. A. 2013. Pengolahan Citra Digital: Konsep & teori. ANDI: Yogyakarta. Hoffstein, J., Pipher, J. & Silverman, J. H. 2008. An Introduction to Mathematical

Cryptography. Springer Science: New York.

Kipper, G. 2004. Investigator's Guide to Steganography. AUERBACH PUBLICATIONS A CRC Press Company: Boca Raton, Florida.

Kromodimoeljo, S. 2010. Teori dan Aplikasi Kriptografi. SPK IT Consulting: Jakarta. Lipschutz, S. & Lipson, M. L. 2007. Schaum’s Outline of: Theory and problems of

discrete mathematics. McGraw-Hill: New York.

Maurer, U. & Basin, D. (Editor). 2010. Advanced Statistical Steganalysis. Springer-Verlag: Berlin.

Mollin, R. A. 2007. An Introduction to Cryptography. 2nd Edition. Chapman & Hall/CRC: Boca Raton, Florida.

Mollin, R. A. 2008. Fundamental Number Theory with Applications. 2nd Edition.

Chapman & Hall/CRC: Boca Raton, Florida.

Muko, G. T., Husni, M. & Studiawan, H. 2012. Aplikasi enkripsi SMS dengan metode Rabin pada Android. Jurnal Teknik Pomits 1 (1): 1-6.

Munir, R. 2006. Kriptografi. Informatika: Bandung.

Nasution, B. 2013. Implementasi sistem keamanan data menggunakan steganografi teknik first of file dan hill cipher kunci ganda. Skripsi. Universitas Sumatera Utara.

Paar, C. & Pelzl, J. 2010. Understanding Cryptography. Springer-Verlag: Berlin. Rădulescu, M. 2008. Public-key cryptography: the RSA and the Rabin cryptosystems.

Tesis. Babeş-Bolyai University.

Rosen, K. H. 2012. Discrete Mathematics and Its Applications. 7th Edition. McGraw-Hill: New York.

Sadikin, R. 2012. Kriptografi untuk Keamanan Jaringan dan Implementasinya dalam Bahasa Java. ANDI: Yogyakarta.

Schneier, B. 1996. Applied Cryptography: Protocols, algorithms and source code in C. 2nd Edition. John Wiley & Sons, Inc.: New Jersey.


(47)

Smart, N. 2004. Cryptography: An introduction. 3rd Edition. University of Bristol. Stallings, W. 2011. Cryptography and Network Security: Principles and practice. 5th

Edition. Pearson Education, Inc.: USA.

Stephens, R. 2013. Essential Algorithms: A practical approach to computer algorithms. John Wiley & Sons, Inc.: Canada.

Sutoyo, T., Mulyanto, E., Suhartono, V., Nurhayati, O. D. & Wijanarto. 2009. Teori Pengolahan Citra Digital. ANDI: Yogyakarta.

Wandani, H. 2012. Implementasi sistem keamanan data dengan menggunakan teknik steganografi end of file (EOF) dan Rabin public key cryptosystem. Skripsi. Universitas Sumatera Utara.

Welschenbach, M. 2005. Cryptography in C an C++. Terjemahan David Kramer. 2nd American Edition. Apress: Berkeley.

Zarlis, M. & Handrizal. 2008. Algoritma dan Pemrograman: Teori dan praktik dalam pascal. Edisi Kedua. USU Press: Medan.


(48)

BAB 3

ANALISIS DAN PERANCANGAN

3.1. Analisis Sistem

Analisis sistem terdiri dari fase-fase berbeda yang mendeskripsikan pengembangan sistem. Dalam tugas akhir ini, ada tiga fase analisis yaitu analisis masalah, analisis kebutuhan dan analisis proses. Analisis masalah bertujuan untuk mengidentifikasi masalah dan menemukan penyebab atau akar dari masalah serta memahami kelayakan masalah. Analisis kebutuhan dilakukan untuk menjelaskan fungsi-fungsi yang ditawarkan dan mampu dikerjakan sistem. Sedangkan analisis proses untuk memodelkan tingkah laku sistem.

3.1.1. Analisis masalah

Seperti yang telah diuraikan pada latar belakang dari skripsi ini, permasalahan yang akan dibahas adalah mengenai keamanan data berupa pesan teks. Gambar 3.1. berikut ini merupakan gambaran masalah secara umum dari penelitian dengan menggunakan diagram Ishikawa (fishbone/cause and effect diagram).


(49)

Diagram Ishikawa diusulkan pertama kali oleh Kaoru Ishikawa dari Jepang. Diagram ini merupakan pendekatan terstruktur yang memungkinkan dilakukan suatu analisis lebih terperinci dalam menemukan penyebab-penyebab suatu masalah, ketidaksesuaian dan kesenjangan yang ada. Selanjutnya, diagram ini dapat digunakan dalam diskusi dengan brainstorming untuk mengidentifikasi mengapa suatu masalah terjadi (Gaspersz, 1997).

Permasalahan utama (effect) pada Gambar 3.1. adalah yang ditunjukkan oleh garis horizontal utama yang berada ditengah, yaitu mengamankan data berupa pesan teks dengan kriptografi dan/atau steganografi. Garis diagonal yang merupakan cabang dari garis horizontal utama merupakan kategori-kategori yang mewakili sebab utama (cause) dari permasalahan utama. Dari setiap kategori memiliki sebab-sebab yang tergolong ke dalam kategori yang bersesuaian dan diantaranya terdapat akar dari permasalahan.

Untuk mendapatkan akar dari permasalahan, perlu dilakukan pengkajian dari diagram Ishikawa dan hal ini dapat dilihat pada Tabel 3.1. dan Tabel 3.2.

Tabel 3.1. Pengkajian Diagram Ishikawa (1) No. Kemungkinan Akar

Permasalahan Diskusi

Akar permasalahan? 1 Metode: Steganografi

metode FOF/EOF.

Terdapat garis atau gradasi berwarna hitam dan ukuran dimensi citra bertambah yang memancing kecurigaan.

Ya

2 Metode: Steganografi metode LSB.

Kualitas citra berubah dan pesan yang disisipkan terbatas. Hal ini dapat diatasi dengan penggunaan citra yang sesuai (dimensi lebih besar).

Tidak

3 Metode: Kriptografi (algoritma Rabin).

Ciphertext terlihat seperti kumpulan karakter acak, namun dapat memancing kecurigaan tentang keberadaan pesan rahasia.

Ya

4 Manusia: Pengirim dan penerima

menginginkan data yang dikirimkan aman.

Dapat digunakan kriptografi dan steganografi yang dianggap aman.


(50)

Tabel 3.2. Pengkajian Diagram Ishikawa (2) No. Kemungkinan Akar

Permasalahan Diskusi

Akar permasalahan? 5 Manusia: Pihak ketiga

memiliki kecurigaan dan ingin tahu.

Jika pihak ketiga teliti, maka kemungkinan pihak ketiga menyadari akan keberadaan pesan rahasia.

Ya

6 Material: Citra berubah dan terlihat

mencurigakan.

Dapat memancing kecurigaan jika perubahan dapat dipersepsi oleh salah satu panca indera dan mencolok.

Ya

7 Material: Kunci dapat diketahui pihak ketiga.

Kunci bersifat aman dan diamankan oleh pengirim dan penerima.

Tidak

8 Mesin: Jalur

pengiriman tidak aman.

Dengan menggunakan kriptografi dan/atau steganografi, tidak masalah jika menggunakan jalur yang tidak aman.

Tidak

9 Mesin: Komputasi yang lama.

Tergantung dari spesifikasi hardware, software, algoritma yang digunakan atau

implementasi.

Tidak

Dari Tabel 3.1. dan Tabel 3.2. dapat disimpulkan akar dari permasalahannya adalah timbulnya kecurigaan dari pihak ketiga terhadap keberadaan pesan rahasia yang disebabkan faktor perubahan citra (terlihatnya garis hitam pada citra dan perubahan ukuran dimensi citra), ciphertext yang mencurigakan dan ketelitian pihak ketiga.

Solusi yang dapat ditawarkan dari akar permasalahan yang telah ditemukan adalah dengan menyembunyikan ciphertext ke dalam citra menggunakan steganografi serta penyembunyian garis atau gradasi warna hitam dan ukuran dimensi citra tidak berubah. Caranya yaitu dengan melakukan steganografi teknik pemetaan titik hitam dengan pencarian sekuensial dan Rabin Cryptosystem.

3.1.2. Analisis kebutuhan

Analisis kebutuhan terbagi dua bagian, yaitu kebutuhan fungsional dan kebutuhan nonfungsional. Kebutuhan fungsional mendeskripsikan aktivitas yang disediakan dan


(51)

harus dipenuhi suatu sistem. Sedangkan kebutuhan nonfungsional mendeskripsikan fitur, karakteristik dan batasan lainnya.

I. Kebutuhan fungsional

1. Fungsi Pembangkit Kunci

Dibutuhkan untuk memudahkan pengguna dalam menentukan kunci yang akan digunakan untuk melakukan enkripsi dan dekripsi. Kunci yang dibangkitkan dapat berupa input langsung dari pengguna atau dibangkitkan secara acak.

2. Fungsi Enkripsi

Dengan memiliki kunci enkripsi, pengguna dapat melakukan enkripsi pesan menjadi ciphertext. Pesan yang dienkripsi dapat berupa input langsung dari pengguna atau pengguna memilih berkas yang berisi pesan yang sudah tersimpan (dengan format *.txt atau *.doc).

3. Fungsi Dekripsi

Dengan memiliki kunci dekripsi dan ciphertext yang bersesuaian, pengguna dapat melakukan dekripsi pesan menjadi plaintext.

4. Fungsi Embed (Penyisipan)

Pesan rahasia disembunyikan ke dalam citra berformat BMP yang dipilih oleh pengguna. Pesan rahasia dapat berupa pesan asli langsung atau ciphertext.

5. Fungsi Ekstrak

Dengan memilih citra berformat BMP yang memiliki pesan rahasia di dalamnya, pengguna dapat memperoleh pesan rahasia berupa plaintext atau ciphertext.

II. Kebutuhan nonfungsional 1. Performa

Perangkat lunak yang dibangun dapat menampilkan dan menyimpan hasil dari fungsi kriptografi dan steganografi yang dilakukan oleh sistem.

2. Mudah dipelajari dan digunakan

Perangkat lunak yang dibangun memiliki tampilan yang user friendly, tampilan yang sederhana dan memaksimalkan penggunaan shortcut.

3. Dokumentasi


(52)

4. Manajemen Kualitas

Perangkat lunak yang dibangun akan memiliki kualitas yang baik yaitu proses kriptografi dan steganografi yang relatif cepat.

5. Kontrol

Perangkat lunak yang dibangun akan menampilkan pesan error untuk setiap input yang tidak sesuai, pembatasan jenis input (hanya karakter, hanya format tertentu) dan pesan error untuk setiap kegagalan dari sistem (jika input tidak dapat ditangani atau diproses).

6. Keamanan

Dalam hal ini yang diamankan adalah kunci yang digunakan. Keamanan kunci tidak diamankan, hanya disimpan untuk kemudahan penggunaan. Namun kunci dapat dihapus dari database.

3.1.3. Analisis proses

Perangkat lunak yang dibangun menggunakan algoritma Rabin Cryptosystem, algoritma Miller-Rabin, algoritma square and multiply, algoritma extended Euclidean, algoritma Chinese Remainder Theorem, pemetaan titik hitam dengan pencarian sekuensial dan menyisipkan pesan rahasia ke dalam titik (yang dianggap) hitam pada citra berformat BMP.

Operasi modulo eksponensial menggunakan metode square and multiply left to right variant serta pencarian inversi modulo dan greatest common divisor menggunakan algoritma extended Euclidean.

Untuk membangkitkan kunci pada algoritma Rabin Cryptosystem, digunakan algoritma Miller-Rabin untuk menemukan bilangan prima atau menentukan keprimaan suatu bilangan.

Untuk dekripsi pada algoritma Rabin, digunakan algoritma Chinese Remainder Theorem dan untuk menentukan hasil dekripsi dari empat kemungkinan hasil dilakukan secara otomatis (autodecrypt), yaitu dengan memilih nilai yang paling kecil. Hal ini berdasarkan pengalaman dalam melakukan dekripsi dari nilai 1 hingga 255 (mencakup karakter dalam ASCII 8 bit) dengan kunci publik yang sama (n) dan lebih besar dari 255 (n > 255), nilai hasil dekripsi yang benar biasanya adalah nilai yang paling kecil.

Sebelum melakukan penyisipan dari pesan rahasia, pada cover-image diperlukan penggantian seluruh pixel yang nilai RGB sama dengan 254 menjadi 255.


(53)

Hal ini dikarenakan setelah penyisipan, pada pixel setelah pixel yang merupakan pesan rahasia akan diubah menjadi pixel dengan nilai RGB sama dengan 254 yang berfungsi sebagai penanda akhir dari pesan dan penanda bahwa sebuah citra merupakan stego-image (pada stego-stego-image, pixel dengan RGB yang bernilai 254 hanya satu pixel). Gambaran dari proses penyisipan pesan ke dalam cover-image dapat dilihat pada Gambar 3.2. berikut.

Gambar 3.2. Ilustrasi Proses Penyisipan Pesan

Penyisipan pesan rahasia dilakukan dengan menguraikan (parsing) nilai satu karakter pesan rahasia (dapat berupa plaintext atau ciphertext) menjadi empat bagian yang nilainya berkisar dari 0 hingga sama dengan 15 (0 ≤ x ≤ 15). Sehingga tetap terlihat hitam (dalam hal ini, terlihat hitam pekat). Lalu nilai x akan disisip pada cover-image dengan cara mengganti nilai pixel yang dianggap hitam dari hasil pemetaan titik hitam menggunakan pencarian sekuensial menjadi x secara berurut. Ilustrasi proses parsing dapat dilihat pada Gambar 3.3. berikut.


(54)

Pencarian titik hitam memerlukan batas toleransi yaitu nilai maksimum pixel pada citra yang dianggap hitam (mt atau maxtolerance). Rentang nilai yang dapat digunakan untuk batas toleransi yaitu dari 15 hingga sama dengan 255 (15 ≤ mt ≤ 255). Jika digunakan batas toleransi yang dibawah nilai 15 (mt < 15), maka akan terjadi kekeliruan dalam proses ekstrak stego-image. Hal ini karena jika pada stego-image terdapat pixel asli (bukan hasil penyisipan pesan) dengan nilai RGB yang lebih kecil atau sama dengan 15 sebelum pixel penanda (dengan nilai RGB sama dengan 254), maka pixel tersebut dianggap sebagai salah satu x (nilai hasil parsing dari pesan rahasia yang ada pada citra).

Penulis menyarankan untuk menggunakan nilai 15 sebagai nilai batas toleransi. Hal ini dikarenakan pada proses penyisipan, pesan rahasia akan diuraikan (parsing) menjadi empat nilai desimal yang nilainya berkisar dari 0 hingga sama dengan 15 sehingga stego-image yang dihasilkan tidak jauh berbeda dengan cover-image.

Penanda stego-image berupa citra yang hanya memiliki satu pixel dengan RGB yang bernilai 254 (penanda). Jika sebuah citra merupakan sebuah stego-image, maka proses ekstrak citra akan dilakukan dengan membaca semua pixel dengan nilai RGB lebih kecil atau sama dengan 15 sampai pixel penanda. Diagram arsitektur dari sistem yang akan dibangun dapat dilihat pada Gambar 3.4. berikut ini.


(55)

3.2. Perancangan Sistem

Perancangan sistem dilakukan untuk memberikan gambaran kepada sistem yang akan dibangun sehingga mempermudah dalam melakukan implementasi ataupun evaluasi.

Sistem dirancang dengan membuat kerangka menu, flowchart, pseudocode, use-case diagram, activity diagram, sequence diagram dan perancangan antarmuka (interface).

3.2.1. Kerangka menu

Secara umum, sistem yang akan dibangun memiliki beberapa menu yang dikelompokkan ke dalam beberapa kategori. Adapun kerangka menu dari sistem yang akan dibangun adalah sebagai berikut.

1. Halaman Utama

Merupakan tampilan awal saat sistem dijalankan. Pada halaman utama dari sistem akan menampilkan kunci publik jika terdapat kunci yang disimpan sebelumnya atau menampilkan tombol pembangkit kunci jika tidak ada kunci yang tersimpan.

2. Menu Fungsi

Terdapat beberapa submenu pada menu fungsi, antara lain: a. Pembangkit kunci

Menu untuk membangkitkan kunci kriptografi Rabin. Kunci dapat dibangkitkan secara acak dari sistem atau ditentukan oleh pengguna. Setelah kunci didapatkan, feature penyimpanan kunci bersifat opsional. Jika kunci ingin disimpan, kunci pada form akan diperiksa kembali sebelum disimpan untuk menghindari kesalahan kunci.

b. Kosongkan database

Berfungsi untuk menghapus kunci yang disimpan sebelumnya. Jika pengguna mengonfirmasi untuk menghapus kunci, maka database kunci akan dikosongkan.

c. Enkripsi dan embed

Pada menu ini, pengguna dapat melakukan proses enkripsi dan/atau embed. d. Ekstrak dan dekripsi


(56)

e. Keluar

Jika pengguna mengonfirmasi untuk keluar dari sistem, maka proses dari sistem akan selesai (aplikasi ditutup).

3. Menu Tentang

Menampilkan identitas singkat dari penulis dan judul dari penelitian. 4. Menu Bantuan

Menampilkan panduan dalam menggunakan aplikasi.

3.2.2. Flowchart square and multiply

Flowchart atau diagram alir merupakan gambar atau bagan yang memperlihatkan urutan dan hubungan antar proses dengan pernyataannya (Zarlis & Handrizal, 2008).

Pada Gambar 3.5. berikut ini merupakan flowchart dari algoritma square and multiply left-to right variant (Smart, 2004).


(57)

Nilai index dari tiap bit pada b pada Gambar 3.5. yaitu index bit paling kanan bernilai t = jumlah bit 1 dan index bit paling kiri bernilai 0. Berikut ini merupakan pseudocode dari algoritma square and multiply left-to-right variant (Smart, 2004).

1. function sam(x,y,z): 2. b = toBinary(y) 3. t = length(b) - 1 4. result = 1

5. for i = 0 to t:

6. result = (result*result) mod z

7. if(b[i] = ’1’): result = (result*x) mod z 8. return result

3.2.3. Flowchart Miller-Rabin

Gambar 3.6. merupakan flowchart dari algoritma Miller-Rabin. Berikut ini adalah pseudocode dari algoritma Miller-Rabin dengan n adalah bilangan bulat positif (Cormen, et al. 2009).

1. function MillerRabin(n):

2. if(n == 2): return “Prima” 3. if((n < 3) or (n mod 2 == 0)): 4. return “Bukan Prima”

5. biner_n = toBinary(n-1) 6. t = get_t(biner_n) 7. u = get_u(biner_n, t) 8. a = differentRandom(n) 9. for i = 0 to length(a)-1:

10. if Witness(a[i], u, n, t): 11. return “Bukan Prima” 12. return “Prima”

1. function Witness(a, u, n, t): 2. x = array

3. x[0] = sam(a, u, n) 4. for i = 1 to t:

5. x[i] = sam(x[i-1],2,n)

6. if x[i]==1 and x[i-1] ≠ 1 and x[i-1] ≠ n–1:


(58)

8. if x[t] ≠ 1: 9. return True 10. return False

1. function get_t(biner_n):

2. t = 0

3. p = length(biner_n)-1 4. for i = p downto 0:

5. if(biner_n[i] == ‘0’):

6. t++

7. if(biner_n[i] == ‘1’):

8. break

9. return t

1. function get_u(biner_n, t):

2. bin_u = biner_n[0:length(biner_n)-t] 3. u = toDecimal(bin_u)

4. return u

1. function differentRandom(n): 2. x = array

3. for i = 0 to length(str(n)): 4. a = random(2, n-1)

5. while a in x:

6. a = random(2, n-1) 7. x[i] = a

8. return x

Berikut ini merupakan penjelasan dari pseudocode di atas. Pseudocode differentRandom(n) berfungsi untuk menentukan bilangan acak yang berbeda antara satu dengan yang lain sebanyak jumlah dari digit bilangan n. Pseudocode get_t(biner_n) berfungsi untuk menentukan nilai t yaitu jumlah bit 0 pada representasi biner bilangan n-1 sebelum digit 1 dari posisi bit paling kanan ke kiri. Pseudocode get_u(biner_n, t) berfungsi untuk menentukan nilai u yaitu nilai desimal u yang memenuhi persamaan 2tu = n-1. Jika fungsi Witness(a, u, n, t) pada pseudocode MillerRabin(n) menghasilkan nilai benar, maka bilangan n merupakan bilangan bukan prima. Dan jika hasil fungsi Witness(a, u, n, t) menghasilkan nilai salah, maka bilangan n merupakan bilangan prima.


(59)

Gambar 3.6. Flowchart dari (A) Algoritma Miller-Rabin dan (B) Fungsi Witness

3.2.4. Flowchart extended Euclidean

Algoritma Extended Euclidean berfungsi untuk menentukan GCD dari dua buah bilangan (a,b) dan menemukan nilai x dan y pada persamaan xa+yb = GCD(a,b)


(60)

(Lipschutz & Lipson, 2007). Gambar 3.7. berikut ini merupakan flowchart dari algoritma Extended Euclidean (Sadikin, 2012).

Gambar 3.7. Flowchart Algoritma Extended Euclidean

Berikut ini adalah pseudocode dari algoritma Extended Euclidean di mana pseudocode ini akan menghasilkan nilai GCD(a,b), x, y (Sadikin, 2012).

1. function extendedEuclidean(a,b):

2. A, B, x, x2, y, y2 = a, b, 1, 0, 0, 1 3. while (B > 0):

4. hasilBagi = A/B

5. sisaBagi = A – hasilBagi * B 6. A, B = B, sisaBagi

7. S = x – hasilBagi * x2 8. x, x2 = x2, S;

9. T = y – hasilBagi * y2 10. y, y2 = y2, T


(61)

3.2.5. Flowchart chinese remainder theorem

Chinese Remainder Theorem digunakan pada proses dekripsi algoritma Rabin, yaitu untuk menyelesaikan dua persamaan dengan modulus yang relatif prima. Gambar 3.8. berikut ini adalah flowchart dari algoritma Chinese Remainder Theorem yang digunakan pada sistem ini (Rosen, 2012).

Gambar 3.8. Flowchart Algoritma Chinese Remainder Theorem

Berikut ini adalah pseudocode dari algoritma Chinese Remainder Theorem yang digunakan pada sistem ini (Rosen, 2012).

1. function CRT(mp, mq, p, q): 2. n = p * q

3. M1 = n / p 4. M2 = n / q

5. gcd, y1, y2 = extendedEuclidean(M1,M2) 6. return mp*M1*y1, mq*M2*y2, n

3.2.6. Flowchart pembangkit kunci

Gambar 3.9. berikut ini adalah flowchart dari pembangkit kunci untuk algoritma Rabin yang digunakan pada penelitian ini.


(62)

Gambar 3.9. Flowchart (A) Pemeriksaan Kunci dan (B) Pembangkit Kunci Secara Acak

Pseudocode dari pembangkit kunci untuk algoritma Rabin terdiri dari dua bagian, yaitu fungsi cekKunci(p, q) dan bangkitkanKunci() seperti sebagai berikut.

1. function cekKunci(p, q):

2. if(p mod 4 == 3) and MillerRabin (p) and (q mod 4 == 3) and MillerRabin (q)

and (p ≠ q) and (length(str(p*q)) ≤ 8):

3. return True

4. return False

1. function bangkitkanKunci(): 2. syarat_tdk_terpenuhi = True 3. while syarat_tdk_terpenuhi:


(63)

5. q = random(3,9999)

6. if cekKunci(p, q):

7. syarat_tdk_terpenuhi = False

8. n = p * q 9. return p, q, n

Fungsi cekKunci(p, q) diperlukan untuk pemeriksaan kunci pada fungsi bangkitkanKunci()dan jika pengguna melakukan input langsung.

3.2.7. Flowchart enkripsi

Flowchart enkripsi terbagi atas dua bagian, yaitu fungsi dasar enkripsi yang berfungsi untuk melakukan enkripsi untuk satu nilai dan fungsi enkripsi yang berfungsi untuk melakukan enkripsi pesan perupa teks seperti yang terlihat pada Gambar 3.10.

Fungsi ord(P[i]) berfungsi untuk mengubah karakter P[i] ke nilai desimal pada ASCII. Dalam hal ini, pesan yang dapat dienkripsi adalah pesan dengan karakter pada ASCII 8 bit seperti yang sudah dijelaskan pada batasan masalah penelitian ini. Berikut ini adalah pseudocode dari proses enkripsi.

1. function enkripsi(P, n): 2. if(P < n):

3. C = sam(P,2,n)

4. return C

5. return False

1. function enkripsiPesan(P, n): 2. C = list

3. for i = 0 to length(P)-1:

4. C.append(enkripsi(ord(P[i]), n)) 5. if C[i] == False: break


(64)

Gambar 3.10. Flowchart (A) Fungsi Dasar Enkripsi dan (B) Fungsi Enkripsi Seperti yang terlihat pada Gambar 3.10. dan pseudocode, jika kunci publik yang digunakan untuk enkripsi lebih kecil atau sama dengan dengan nilai desimal dari karakter pada sebuah pesan, maka fungsi akan mengembalikan nilai salah (false) yang berarti kesalahan pada proses enkripsi atau proses enkripsi tidak dapat dilakukan.

3.2.8. Flowchart dekripsi

Pada algoritma Rabin, terdapat empat hasil dekripsi dan penerima pesan harus menentukan pesan yang benar. Terdapat beberapa cara yang dapat dilakukan untuk dapat menentukan hasil dekripsi yang benar, seperti menggandakan pesan atau menggandakan nilai bit dari pesan sebelum dienkripsi dan hasil yang memiliki nilai yang berulang merupakan kemungkinan hasil dekripsi yang benar.

Jika pesan yang dienkripsi jumlahnya sedikit, maka penerima pesan relatif mudah dalam menentukan hasil dekripsi. Namun jika pesan yang dienkripsi jumlahnya


(65)

banyak, maka akan timbul kesulitan bagi penerima pesan dalam menentukan hasil dekripsi. Penulis sudah mencoba melakukan enkripsi (menggunakan kunci publik yang lebih besar dari 255) dan dekripsi untuk nilai yang mencakup karakter pada ASCII 8 bit (1 sampai dengan 255) dan memberikan pengalaman bahwa hasil dekripsi yang benar biasanya adalah nilai yang paling kecil dari keempat hasil dekripsi. Berdasarkan pengalaman tersebut, penulis melakukan modifikasi dalam proses dekripsi pada penelitian ini yaitu dengan melakukan proses autodekripsi (penerima pesan tidak direpotkan dalam menentukan nilai dekripsi yang dianggap benar). Adapun flowchart dari proses dekripsi pada penelitian ini dapat dilihat pada Gambar 3.11.

Berikut ini adalah pseudocode dari proses dekripsi pada penelitian ini. 1. function autodekripsi(C, p, q):

2. mp = sam(C, (p+1)/4, p) 3. mq = sam(C, (q+1)/4, q) 4. x, y, n = CRT(mp,mq,p,q) 5. P1 = (x + y) mod n

6. P2 = (x – y) mod n 7. P3 = (-x + y) mod n 8. P4 = (-x – y) mod n

9. return min(P1, P2, P3, P4)

1. function dekripsi(C, p, q): 2. Psn = []

3. for i = 0 to length(C)-1:

4. Psn.append(chr(autodekripsi(C[i],p,q))) 5. return join(Psn)

Pada fungsi dekripsi pesan, fungsi chr() akan mengubah nilai hasil autodekripsi ke bentuk karakter ASCII dan join(Psn) berfungsi untuk membentuk karakter-karakter yang telah disimpan pada list menjadi string pesan.


(66)

Gambar 3.11. Flowchart (A) Fungsi Autodekripsi dan (B) Fungsi Dekripsi Pesan

3.2.9. Flowchart pemetaan titik hitam

Pemetaan titik hitam digunakan dalam penyisipan pesan rahasia ke dalam citra dan berfungsi untuk mengetahui index atau posisi pixel yang dianggap hitam. Batas toleransi warna yang dianggap hitam (mt) adalah nilai maksimum dari warna yang dianggap hitam. Pada penelitian ini, nilai dari mt dapat ditetetapkan mulai dari 15 hingga sama dengan 255. Walaupun demikian, penulis menyarankan untuk memberikan nilai mt = 15 untuk hasil penyisipan (embedding) yang lebih baik.

Langkah-langkah dalam pemetaan titik hitam digambarkan pada Gambar 3.12. berikut ini.


(67)

Gambar 3.12. Flowchart Pemetaan Titik Hitam

Langkah-langkah dalam melakukan pemetaan titik hitam dalam bentuk pseudocode adalah seperti berikut.

1. function sequentialSearch(pixel, mt): 2. htm = list

3. for i = 0 to length(pixel)-2:

4. if(pixel[i][0] <= mt and pixel[i][1] <= mt and pixel[i][2] <= mt):

5. htm.append(i)

6. return htm

Nilai pixel berupa tuple, list ataupun larik yang berisi nilai R, G dan B dari sebuah pixel. Pencarian dilakukan dari index 0 hingga jumlah pixel dalam citra dikurang


(68)

dengan 2 karena pixel paling akhir dari citra akan digunakan sebagai penanda jika pada pixel sebelumnya merupakan pixel yang dianggap hitam.

3.2.10. Flowchart penyisipan

Gambar 3.13. berikut ini adalah flowchart dari penyisipan pesan ke dalam citra.


(69)

Sebelum melakukan penyisipan, perlu dilakukan beberapa proses yaitu penguraian (parsing) nilai pesan rahasia, penyaringan (filter) citra untuk mengganti seluruh pixel dengan nilai RGB sama dengan 254 menjadi 255 dan dilanjutkan kepada proses pemetaan titik hitam.

Tujuan dari proses parsing nilai pesan rahasia adalah untuk memperoleh nilai yang cukup untuk dikatakan hitam pada representasi warna RGB sehingga pada proses penggantian warna pada cover-image tidak begitu mempengaruhi kualitas warna pada citra. Alasan penulis memilih warna hitam adalah karena nilai representasi warna hitam pada RGB relatif lebih kecil daripada warna lainnya dan hal ini berhubungan dengan nilai hasil parsing suatu bilangan.

Jika nilai hasil parsing menjadi relatif besar dan disisip pada pixel dengan nilai RGB yang relatif kecil atau sebaliknya, maka akan mempengaruhi kualitas citra tersebut berupa perbedaan warna yang semakin mencolok. Mempertimbangkan hal tersebut, penulis memilih untuk menghasilkan nilai parsing yang relatif kecil untuk mengganti nilai yang relatif kecil pula karena lebih mudah untuk membagi suatu bilangan menjadi kecil dan menggabungkannya kembali ke bentuk semula daripada memperbesar nilai suatu bilangan dalam rentang 0 hingga sama dengan 255 untuk menghasilkan representasi warna RGB yang tidak jauh berbeda.

Nilai hasil parsing yang penulis tetapkan adalah bilangan dalam rentang dari 0 hingga sama dengan 15. Berdasarkan pengamatan penulis, nilai dari 0 hingga sama dengan 15 pada representasi warna RGB akan menghasilkan warna yang relatif terlihat sama (hitam). Nilai 15 dipilih karena jumlah bit pada representasi binernya sebanyak 4 bit dan merupakan nilai maksimal untuk biner dengan panjang biner sebanyak 4 bit. Selain itu, rentang nilai 15 relatif tidak jauh terhadap nilai 0.

Proses parsing dilakukan dengan membagi nilai biner dari suatu bilangan menjadi beberapa bagian. Berdasarkan percobaan yang penulis lakukan, panjang atau jumlah bit maksimal suatu ciphertext hasil enkripsi (menggunakan algoritma Rabin) dari nilai suatu pesan rahasia (sesuai ASCII 8 bit) dengan beberapa kunci publik sepanjang 64 bit yang berbeda-beda adalah sebanyak 16 bit. Dari percobaan tersebut, penulis menetapkan untuk menyamakan panjang bit dari tiap nilai yang akan disisip ke citra sepanjang 16 bit yaitu dengan menambahkan sejumlah bit 0 pada bit paling kiri hingga panjang bit nilai yang akan disisipkan tersebut menjadi 16 bit.


(1)

Bab 4 Implementasi dan Pengujian

4.1. Implementasi 78

4.1.1. Tampilan antarmuka halaman utama 78 4.1.2. Tampilan antarmuka halaman pembangkit kunci 80 4.1.3. Tampilan antarmuka halaman enkripsi dan embed 80 4.1.4. Tampilan antarmuka halaman ekstrak dan dekripsi 82 4.1.5. Tampilan antarmuka halaman tentang 83 4.1.6. Tampilan antarmuka halaman bantuan 84

4.2. Pengujian 85

4.2.1. Skenario pembangkitan kunci 85

4.2.2. Skenario enkripsi 87

4.2.3. Skenario penyisipan 88

4.2.4. Skenario ekstraksi 93

4.2.5. Skenario dekripsi 94

4.2.6. Hasil pengujian enkripsi 97

4.2.7. Hasil pengujian dekripsi 99

4.2.8. Hasil pengujian penyisipan 106

4.2.9. Hasil pengujian ekstraksi 113

Bab 5 Kesimpulan dan Saran

5.1. Kesimpulan 127

5.2. Saran 128


(2)

DAFTAR TABEL

Halaman Tabel 2.1. Penyelesaian Contoh Soal Inversi Modulo 18 Tabel 2.2. Penyelesaian Contoh Soal Square and Multiply Left-to Right Variant 19

Tabel 2.3. Matriks dari Gambar 2.11. 34

Tabel 3.1. Pengkajian Diagram Ishikawa (I) 38

Tabel 3.2. Pengkajian Diagram Ishikawa (II) 39

Tabel 3.3. Use-Case Narrative Simpan Kunci 65

Tabel 3.4. Use-Case Narrative Menentukan Kunci 66

Tabel 3.5. Use-Case Narrative Bangkitkan Kunci Secara Acak 66 Tabel 3.6. Use-Case Narrative Sisip Pesan ke Citra (I) 67 Tabel 3.7. Use-Case Narrative Sisip Pesan ke Citra (II) 68

Tabel 3.8. Use-Case Narrative Enkripsi Pesan 69

Tabel 3.9. Use-Case Narrative Ekstrak Citra 70

Tabel 3.10. Use-Case Narrative Dekripsi Pesan 71

Tabel 4.1. Nilai RGB dari Cover-Image pada Skenario Penyisipan 89 Tabel 4.2. Nilai RGB dari Stego-Image pada Skenario Penyisipan 91 Tabel 4.3. Penyelesaian Extended Euclidean pada Skenario Dekripsi 95 Tabel 4.4. Hasil Pengujian Enkripsi dengan Variasi Panjang Plaintext 98 Tabel 4.5. Hasil Pengujian Enkripsi dengan Variasi Besar Kunci Publik 99 Tabel 4.6. Hasil Pengujian Dekripsi dengan Variasi Panjang Ciphertext 100 Tabel 4.7. Hasil Pengujian Dekripsi dengan Variasi Kunci 101 Tabel 4.8. Pengujian Keutuhan Data terhadap Satu Kunci 103 Tabel 4.9. Pengujian Proses Dekripsi pada Sistem dengan Kunci Berbeda 104 Tabel 4.10. Informasi Citra (Cover-Image) pada Pengujian Penyisipan 107 Tabel 4.11. Hasil Pengujian Penyisipan dengan Variasi Panjang Pesan Rahasia 107 Tabel 4.12. Hasil Pengujian Penyisipan dengan Variasi Cover-Image 109 Tabel 4.13. Perbandingan Citra dengan Batas Toleransi Sebesar 255 113 Tabel 4.14. Pengujian Aspek Recovery dari Proses Ekstraksi 114 Tabel 4.15. Tampilan dan Informasi Cover-Image

pada Pengujian Aspek Robustness 117

Tabel 4.16. Tampilan dan Informasi Stego-Image

pada Pengujian Aspek Robustness 117

Tabel 4.17. Tampilan dan Informasi Stego-Image Modifikasi I 118 Tabel 4.18. Tampilan dan Informasi Stego-Image Modifikasi II 119 Tabel 4.19. Tampilan dan Informasi Stego-Image Modifikasi III 119 Tabel 4.20. Tampilan dan Informasi Stego-Image Modifikasi IV 120 Tabel 4.21. Tampilan dan Informasi Stego-Image Modifikasi V 120 Tabel 4.22. Tampilan dan Informasi Stego-Image Modifikasi VI 121 Tabel 4.23. Tampilan dan Informasi Stego-Image Modifikasi VII 122 Tabel 4.24. Tampilan dan Informasi Stego-Image Modifikasi VIII 122 Tabel 4.25. Tampilan dan Informasi Stego-Image Modifikasi IX 123 Tabel 4.26. Tampilan dan Informasi Stego-Image Modifikasi X 124 Tabel 4.27. Tampilan dan Informasi Stego-Image Modifikasi XI 124


(3)

Tabel 4.28. Tampilan dan Informasi Stego-Image Modifikasi XII 125 Tabel 4.29. Tampilan dan Informasi Stego-Image Modifikasi XIII 125 Tabel 4.30. Tampilan dan Informasi Stego-Image Modifikasi XIV 126


(4)

DAFTAR GAMBAR

Halaman

Gambar 2.1. Skema Proses Enkripsi dan Dekripsi 7

Gambar 2.2. Skema Sistem Kriptografi Simeti 9

Gambar 2.3. Skema Kriptografi Asimetri Kunci Publik 10 Gambar 2.4. Skema Kriptografi Asimetri Nirkunci Publik 12

Gambar 2.5. Gradasi Warna pada Citra Biner 27

Gambar 2.6. Contoh Citra Biner 27

Gambar 2.7. Contoh Citra Grayscale 27

Gambar 2.8. Contoh Citra Warna 28

Gambar 2.9. Skema Sistem Steganografi 31

Gambar 2.10. Pencarian Linier di Dalam Larik yang Terurut 33 Gambar 2.11. Citra Berdimensi 10 × 10 pixels (RGB, format BMP) 34

Gambar 3.1. Diagram Ishikawa 37

Gambar 3.2. Ilustrasi Proses Penyisipan Pesan 42

Gambar 3.3. Ilustrasi Proses Parsing 42

Gambar 3.4. Diagram Arsitektur dari Sistem yang Akan Dibangun 43 Gambar 3.5. Flowchart Square and Multiply Left-to-Right Variant 45 Gambar 3.6. Flowchart dari (A) Algoritma Miller-Rabin dan (B) Fungsi Witness 48 Gambar 3.7. Flowchart Algoritma Extended Euclidean 49 Gambar 3.8. Flowchart Algoritma Chinese Remainder Theorem 50 Gambar 3.9. Flowchart (A) Pemeriksaan Kunci dan

(B) Pembangkit Kunci Secara Acak 51

Gambar 3.10. Flowchart (A) Fungsi Dasar Enkripsi dan (B) Fungsi Enkripsi 53 Gambar 3.11. Flowchart (A) Fungsi Autodekripsi dan (B) Fungsi Dekripsi Pesan 55

Gambar 3.12. Flowchart Pemetaan Titik Hitam 56

Gambar 3.13. Flowchart Penyisipan 57

Gambar 3.14. Flowchart Ekstrak Citra 61

Gambar 3.15. Use-Case Diagram 64

Gambar 3.16. Activity Diagram 72

Gambar 3.17. Sequence Diagram Pembangkitan Kunci 72 Gambar 3.18. Sequence Diagram Proses Enkripsi dan Embed 73 Gambar 3.19. Sequence Diagram Proses Ekstrak dan Dekripsi 73 Gambar 3.20. Tampilan Halaman Utama Tanpa Kunci Tersimpan 74 Gambar 3.21. Tampilan Halaman Utama dengan Kunci Tersimpan 74

Gambar 3.22. Tampilan Form Pembangkit Kunci 75

Gambar 3.23. Tampilan Form Enkripsi dan Embed 75

Gambar 3.24. Tampilan Form Ekstrak dan Dekripsi 76

Gambar 3.25. Tampilan Halaman Tentang 76

Gambar 3.26. Tampilan Halaman Bantuan 77

Gambar 4.1. Antarmuka Halaman Utama Saat Tidak Ada Kunci Tersimpan 79 Gambar 4.2. Antarmuka Halaman Utama Saat Ada Kunci Tersimpan 79

Gambar 4.3. Antarmuka Halaman Pembangkit Kunci 80

Gambar 4.4. Antarmuka Halaman Enkripsi dan Embed 81


(5)

Gambar 4.5. Antarmuka Halaman Ekstrak dan Dekripsi 82

Gambar 4.6. Antarmuka Halaman Tentang 84

Gambar 4.7. Antarmuka Halaman Bantuan 84

Gambar 4.8. Pengujian Sistem dengan Skenario Pembangkitan Kunci 86 Gambar 4.9. Pengujian Sistem dengan Skenario Enkripsi 88 Gambar 4.10. Tampilan Cover-Image pada Skenario Penyisipan 89 Gambar 4.11. Pengujian Sistem dengan Skenario Penyisipan 90 Gambar 4.12. Tampilan Stego-Image pada Skenario Penyisipan 90 Gambar 4.13. Pengujian Sistem dengan Skenario Ekstraksi 93 Gambar 4.14. Pengujian Sistem dengan Skenario Dekripsi 95 Gambar 4.15. Grafik Pengaruh Panjang Plaintext dengan Lama Proses Enkripsi 98 Gambar 4.16. Grafik Pengaruh Besar Kunci Publik dengan Lama Proses Enkripsi 99 Gambar 4.17. Grafik Pengaruh Panjang Ciphertext dengan Lama Proses Dekripsi 101 Gambar 4.18. Grafik Hasil Pengujian Dekripsi Pesan dengan Variasi Kunci 102 Gambar 4.19. Grafik Hasil Pengujian Penyisipan dengan Variasi Panjang Pesan 108 Gambar 4.20. Grafik Pengaruh Ukuran Citra Terhadap Lama Proses Penyisipan 110 Gambar 4.21. Grafik Pengaruh Ukuran Dimensi

Terhadap Lama Proses Penyisipan 110

Gambar 4.22. Grafik Pengaruh Jumlah Titik Hitam

Terhadap Lama Proses Penyisipan 111

Gambar 4.23. Grafik Perbandingan Width dan Height pada Dimensi Citra

Terhadap Lama Proses Penyisipan 111

Gambar 4.24. Grafik Pengaruh Ukuran Citra (Size)

dari Pengujian Proses Ekstraksi 115

Gambar 4.25. Grafik Pengaruh Dimensi Citra dari Pengujian Proses Ekstraksi 115 Gambar 4.26. Grafik Perbandingan Lama Proses Penyisipan dan Proses Ekstraksi 116


(6)

DAFTAR LAMPIRAN

Halaman

Lampiran 1 Urutan Peraturan Pengisian Angket 131

Lampiran 2 Angket 132

Lampiran 3 Listing Program 152

Lampiran 4 Daftar Riwayat Hidup (Curriculum Vitae) 173