LAMPIRAN A : LISTING PROGRAM
File : chrome.manifest
content addonta chrome/
style chrome://global/content/customizeToolbar.xul chrome://addonta/content/button.css
# Thunderbird compose Overlay chrome:
//messenger/content/messengercompose/messengercompose.xul chrome://addonta/content/button.xul
File : install.rdf
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <Description
about="urn:mozilla:install-manifest"
em:name="Proyek Tugas Akhir S-1 Ilmu Komputer USU"
em:description="Add On Keamanan EMail dengan Kriptografi XOR Menggunakan Threee Pass Protocol dan Kompresi Lempel Ziv Welch (LZW)"
em:creator="Brikson Hara Donald Barus - 081401037" em:id="addonenkripsikompresi@ilmukomputer.usu.ac.id" em:version="1.0"
em:iconURL="chrome://addonta/content/icon.png" > <em:targetApplication><!-- Thunderbird -->
<Description
em:id="{3550f703-e582-4d05-9a08-453d09bdfdc6}" em:minVersion="1.4"
em:maxVersion="11.*" /> </em:targetApplication> <em:file>
<Description
about="urn:mozilla:extension:addonta" em:package="content/addonta/" /> </em:file>
</RDF>
File : button.css
#button-enkripsi, #wrapper-button-enkripsi {list-style-image:
url("chrome://addonta/content/buttonenkripsi.png");} .addonta
{-moz-image-region: rect( 0px 24px 24px 0px);} .addonta:hover
{-moz-image-region: rect(24px 24px 48px 0px);}
[iconsize="small"] .addonta
{-moz-image-region: rect( 0px 40px 16px 24px);} [iconsize="small"] .addonta:hover
{list-style-image:
url("chrome://addonta/content/buttondekripsi.png");}
.addonta
{-moz-image-region: rect( 0px 24px 24px 0px);} .addonta:hover
{-moz-image-region: rect(24px 24px 48px 0px);}
[iconsize="small"] .addonta
{-moz-image-region: rect( 0px 40px 16px 24px);} [iconsize="small"] .addonta:hover
{-moz-image-region: rect(24px 40px 40px 24px);}
button.xul
/*Referensi utama perancangan dokumen XUL overlay diperoleh pada https://developer.mozilla.org/ */
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/css"
href="chrome://addonta/content/button.css"?> <!DOCTYPE overlay >
<overlay id="addonta-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
<script type="application/javascript"
src="chrome://addonta/content/scriptForAddOn.js"/> <!-- Thunderbird compose -->
<toolbarpalette id="MsgComposeToolbarPalette"> <toolbarbutton id="button-enkripsi"/>
<toolbarbutton id="button-dekripsi"/> </toolbarpalette>
<toolbarbutton id="button-enkripsi" label="Enkripsi"
tooltiptext="Digunakan untuk melakukan Enkripsi dan Proses Kompresi-Dekompresi yang diperlukan" oncommand="cryptography.encryptionTPPControlProcess()"
class="toolbarbutton-1 chromeclass-toolbar-additional addonta" />
<toolbarbutton id="button-dekripsi" label="Dekripsi"
tooltiptext="Digunakan untuk melakukan Dekripsi dan Proses Kompresi-Dekompresi yang diperlukan" oncommand="cryptography.decryptionTPPControlProcess()"
class="toolbarbutton-1 chromeclass-toolbar-additional addonta" />
</overlay>
File : scriptForAddOn.js
plainText:'', key:'',
cipherText:'', inputText:'',
getBodyText: function(){
var composer = document.getElementById('msgcomposeWindow'); var source = composer.getElementsByAttribute('id', 'content-frame').item(0).contentDocument.documentElement;
this.inputText = source.textContent; },
lcgKeyGenerator: function(lengthOfKey){ var time= new Date;
var a=time.getMinutes(); var b=time.getSeconds(); var x=0, x1=0;
this.key=''; do{
x1=((a*x)+b)%64; x=x1;
this.key+=encoDecoding.getBiner(x); } while((lengthOfKey-this.key.length)>=6)
if(((lengthOfKey-this.key.length)<6)&&((lengthOfKey-this.key.length)>0)){
x1=((a*x)+b)%64; x=x1;
var temp=encoDecoding.getBiner(x);
this.key+=temp.slice(6-(lengthOfKey-this.key.length)); }
},
writeOnCompose: function(textToWritten){ var editor = GetCurrentEditor();
var editor_type = GetCurrentEditorType(); editor.beginTransaction();
editor.beginningOfDocument(); // seek to beginning editor.selectAll();
editor.cut();
editor.selectAll(); editor.cut();
editor.insertText(textToWritten); editor.endTransaction();
},
encryptionTPPControlProcess: function(){ this.getBodyText();
if(this.inputText.length!=0){
var flag=this.inputText.slice(0,3); if(flag=='[1]'){
this.plainText=this.inputText.slice(3);
var start= new Date().getTime();
var binPlain=encoDecoding.base64Decode(this.plainText); var timeP= new Date().getTime()-start;
start= new Date().getTime();
var binCipher=this.encrypt(binPlain); timeP= new Date().getTime()-start;
alert('Waktu Enkripsi Tahap-2 = '+timeP+' milisecond');
if(binCipher!=''){
start= new Date().getTime();
this.cipherText=encoDecoding.base64Encode(binCipher); timeP= new Date().getTime()-start;
alert('Waktu Encoding Tahap-2 = '+timeP+' milisecond');
this.writeOnCompose('[2]'+this.cipherText); var dir = ioFileAccessing.getDirectory('ProfD'); var fin='\\extensions\\Key_Enkripsi_2.txt'; var path=dir.path + fin;
var fileIn = ioFileAccessing.open(path); ioFileAccessing.write(fileIn,this.key);
alert('Terima Kasih.. \nProses Enkripsi Berhasil (Silahkan Lanjutkan Proses Selanjutnya)');
}
} else if(flag=='[2]'){
alert('Maaf Proses Three Pass Protocol (Tahap Ke-3) yang seharusnya anda lakukan adalah Dekripsi');
} else if(flag=='[3]'){
alert('Maaf Proses Three Pass Protocol (Tahap Ke-4) yang seharusnya anda lakukan adalah Dekripsi');
} else {
this.plainText=this.inputText;
alert('Panjang Plainteks = ' +this.plainText.length); alert('Panjang Bit Plainteks =
'+this.plainText.length*8);
var start=new Date().getTime();
var compressed=lzwCompression.compress(this.plainText); var timeP= new Date().getTime()-start;
alert('Waktu Kompresi = '+timeP+' milisecond');
var dicBitLength=lzwCompression.getDictionaryBitLength(); var
binCompressed=lzwCompression.binarizeCompressed(compressed); alert('Panjang Bit Kamus = '+dicBitLength); alert('Panjang Bit Hasil Kompresi =
'+binCompressed.length);
var start= new Date().getTime();
var binCipher=this.encrypt(binCompressed); var timeP= new Date().getTime()-start;
alert('Waktu Enkripsi Tahap-1 = '+timeP+' milisecond');
if(binCipher!=''){
start= new Date().getTime();
this.cipherText=encoDecoding.base64Encode(binCipher); timeP= new Date().getTime()-start;
this.writeOnCompose('[1]'+this.cipherText);
var dir = ioFileAccessing.getDirectory('ProfD');
var fin='\\extensions\\Key_Enkripsi_1.txt'; var path=dir.path + fin;
var fileIn = ioFileAccessing.open(path); ioFileAccessing.write(fileIn,this.key);
fin='\\extensions\\Panjang Bit Kamus.txt'; path=dir.path + fin;
fileIn = ioFileAccessing.open(path);
ioFileAccessing.write(fileIn,String(dicBitLength));
alert('Terima Kasih.. \nProses Enkripsi Berhasil (Silahkan Lanjutkan Proses Selanjutnya)');
} }
} else {
alert('Maaf, Anda belum memasukkan pesan!'); }
},
decryptionTPPControlProcess: function(){ this.getBodyText();
if(this.inputText.length!=0){
var flag=this.inputText.slice(0,3); if(flag=='[1]'){
alert('Maaf Proses Three Pass Protocol (Tahap Ke-2) yang seharusnya anda lakukan adalah Enkripsi');
} else if(flag=='[2]'){
this.cipherText=this.inputText.slice(3);
var dir = ioFileAccessing.getDirectory('ProfD'); var fin='\\extensions\\Key_Enkripsi_1.txt'; var path=dir.path + fin;
var fileIn = ioFileAccessing.open(path); this.key = ioFileAccessing.read(fileIn);
dir = ioFileAccessing.getDirectory('ProfD'); fin='\\extensions\\Panjang Bit Kamus.txt'; path=dir.path + fin;
fileIn = ioFileAccessing.open(path);
var dicBitLenth = eval(ioFileAccessing.read(fileIn));
var start= new Date().getTime();
var binCipher=encoDecoding.base64Decode(this.cipherText); var timeP= new Date().getTime()-start;
alert('Waktu Decoding Tahap-3 = '+timeP+' milisecond');
start= new Date().getTime();
var binPlain=this.decrypt(binCipher); timeP= new Date().getTime()-start;
alert('Waktu Dekripsi Tahap-3 = '+timeP+' milisecond');
if(binPlain!=''){
start= new Date().getTime();
timeP= new Date().getTime()-start;
alert('Waktu Encoding Tahap-3 = '+timeP+' milisecond');
this.writeOnCompose('[3]'+String(dicBitLenth)+'&'+this.plainText); alert('Terima Kasih.. \nProses Dekripsi Berhasil
(Silahkan Lanjutkan Proses Selanjutnya)'); }
} else if(flag=='[3]'){
var procCipherText=this.inputText.slice(3);
var signLoc=0;
for(var i=0;i<=procCipherText.length-1;i++){ if(procCipherText.charAt(i)=='&'){
signLoc=i;
i=procCipherText.length; }
}
var dicBinLength=eval(procCipherText.slice(0,signLoc)); this.cipherText=procCipherText.slice(signLoc+1);
var dir = ioFileAccessing.getDirectory('ProfD'); var fin='\\extensions\\Key_Enkripsi_2.txt'; var path=dir.path + fin;
var fileIn = ioFileAccessing.open(path); this.key = ioFileAccessing.read(fileIn);
var start= new Date().getTime();
var binCipher=encoDecoding.base64Decode(this.cipherText); var timeP= new Date().getTime()-start;
alert('Waktu DeCoding Tahap Akhir = '+timeP+' milisecond');
start= new Date().getTime();
var binPlain=this.decrypt(binCipher); timeP= new Date().getTime()-start;
alert('Waktu Dekripsi Tahap Akhir = '+timeP+' milisecond');
if(binPlain!=''){
lzwCompression.setDictionaryBitLength(dicBinLength); var
compressedPlain=lzwCompression.decCompressed(binPlain);
start= new Date().getTime();
this.plainText=lzwCompression.decompress(compressedPlain); timeP= new Date().getTime()-start;
alert('Waktu Dekompresi Tahap Akhir = '+timeP+' milisecond');
this.writeOnCompose(this.plainText);
alert('Terima Kasih.. \nProses Dekripsi Berhasil, Proses Terakhir Telah Berhasil Dilakukan.');
alert('Maaf Proses Three Pass Protocol (Tahap Pertama) yang seharusnya anda lakukan adalah Enkripsi'); }
} else {
alert('Maaf, Anda belum memasukkan pesan!'); }
},
xorOperation: function(opr1,opr2){ var result = '';
if(opr1.length==opr2.length){
for(var i=0;i<=opr1.length-1;i++){
var temp=eval(opr1.charAt(i))^eval(opr2.charAt(i)); result+=temp;
} } else {
alert('Mohon Maaf Operasi XOR Tidak Dapat Dilakukan terdapat Kesalahan.'+'\nMohon Ulangi Proses Three Pass Protocol');
}
return result; },
encrypt: function(binPlain){
this.lcgKeyGenerator(binPlain.length);
var binCipher=this.xorOperation(binPlain,this.key); return binCipher;
},
decrypt: function(binCipher){
var binPlain=this.xorOperation(binCipher,this.key); return binPlain;
} },
lzwCompression={
dictionary:new Array(), dictionaryBitLength:0,
setDictionary: function(){ this.dictionary=[]; for(var i=0;i<=255;i++){
this.dictionary[i]=String.fromCharCode(i); }
this.dictionaryBitLength=(this.dictionary.length-1).toString(2).length;
},
getIndexfromDictionary:function(lookChars){
var dictionaryIndex=this.dictionary.indexOf(lookChars); return dictionaryIndex;
},
getDictionaryBitLength:function(){ return this.dictionaryBitLength; },
setDictionaryBitLength:function(dicBitLength){ this.dictionaryBitLength=dicBitLength; },
var stream='';
if(indexOfDictionary<=this.dictionary.length-1){ stream=this.dictionary[indexOfDictionary]; }
return stream; },
addToDictionary: function(addedStream){ var lastIndex=this.dictionary.length; lastIndex++;
this.dictionary[lastIndex]=addedStream;
this.dictionaryBitLength=(lastIndex-1).toString(2).length;
},
compress: function(inputStream){ this.setDictionary();
var compressed=new Array(); var resultCount=0;
var lookAhead='';
for(var i=0;i<=inputStream.length-1;i++){ var nextChar=inputStream.charAt(i); var lookAheadNext=lookAhead+nextChar;
var indDictionary=this.getIndexfromDictionary(lookAheadNext); if(indDictionary != -1){
lookAhead=lookAheadNext; } else {
compressed[resultCount]=this.getIndexfromDictionary(lookAhead); resultCount++;
this.addToDictionary(lookAheadNext); lookAhead=nextChar;
}
if(i==inputStream.length-1){
compressed[resultCount]=this.getIndexfromDictionary(lookAhead); }
}
return compressed; },
decompress:function(inputStream){ this.setDictionary();
var uncompressed=''; var resultCount=0; var prev='';
var prev=this.getStreamfromDictionary(inputStream[0]); uncompressed+=prev;
resultCount++; var entry;
for(var i=1;i<=inputStream.length-1;i++){
var temp=this.getStreamfromDictionary(inputStream[i]); if(temp!=''){
entry=temp; } else {
uncompressed+=entry; resultCount++;
this.addToDictionary(prev+entry.charAt(0)); prev=entry;
}
return uncompressed; },
binarizeCompressed: function(inputDecimals){ var binCompressedResult='';
for(var i=0;i<=inputDecimals.length-1;i++){ var temp=inputDecimals[i].toString(2);
var lengthOfPadding=this.dictionaryBitLength-temp.length; var padding='';
for(var j=0;j<=lengthOfPadding-1;j++){ padding+='0';
}
temp=padding+temp;
binCompressedResult+=temp; }
return binCompressedResult; },
decCompressed: function(inputBin){ var counter=0;
var decimalOfBit=new Array(); var index=0;
do{ var
temp=inputBin.substring(counter,(counter+this.dictionaryBitLength)); var dec=0;
for(var i=0;i<=this.dictionaryBitLength-1;i++){ var bitval=eval(temp.charAt(i));
var valOfBit=Math.pow(2,(this.dictionaryBitLength-(i+1)));
dec+=(bitval*valOfBit); }
decimalOfBit[index]=dec; index++;
counter+=this.dictionaryBitLength; } while((inputBin.length-counter)>=9)
return decimalOfBit; }
},
encoDecoding={
base64CharSet:'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01 23456789+/',
paddingSign: new Array("!","@","#","$","%"), base64Encoded:'',
getDecimal: function(binStream){ var dec=0;
dec+=eval(binStream.charAt(3))*4; dec+=eval(binStream.charAt(4))*2; dec+=eval(binStream.charAt(5))*1; return dec;
},
getBiner: function(dec){ var temp=dec.toString(2); var padding=6-temp.length; var bin='';
switch(padding){
case 1: bin='0'+temp; break; case 2: bin='00'+temp; break; case 3: bin='000'+temp; break; case 4: bin='0000'+temp; break; case 5: bin='00000'+temp; break; default : bin=temp;
}
return bin; },
base64Encode: function(unencodedBits){ var counter=0;
var temp=''; var index=0;
this.base64Encoded=''; do{
temp=unencodedBits.substring(counter,counter+6); counter+=6;
index=this.getDecimal(temp);
this.base64Encoded+=this.base64CharSet.charAt(index);
}while((unencodedBits.length-counter)>=6)
if((unencodedBits.length-counter)==1){
temp='00000'+unencodedBits.slice(counter); index=this.getDecimal(temp);
this.base64Encoded+=this.base64CharSet.charAt(index)+this.paddingS ign[0];
}
if((unencodedBits.length-counter)==2){
temp='0000'+unencodedBits.slice(counter); index=this.getDecimal(temp);
this.base64Encoded+=this.base64CharSet.charAt(index)+this.paddingS ign[1];
}
if((unencodedBits.length-counter)==3){ temp='000'+unencodedBits.slice(counter); index=this.getDecimal(temp);
this.base64Encoded+=this.base64CharSet.charAt(index)+this.paddingS ign[2];
}
temp='00'+unencodedBits.slice(counter); index=this.getDecimal(temp);
this.base64Encoded+=this.base64CharSet.charAt(index)+this.paddingS ign[3];
}
if((unencodedBits.length-counter)==5){ temp='0'+unencodedBits.slice(counter); index=this.getDecimal(temp);
this.base64Encoded+=this.base64CharSet.charAt(index)+this.paddingS ign[4];
}
return this.base64Encoded; },
base64Decode: function(encoded){ var unencodedBits='';
var sign=0;
var len=encoded.length;
var lastChar=encoded.charAt(len-1);
for(var i=0;i<=4;i++){
if(lastChar==this.paddingSign[i]){ sign=6-(i+1);
} }
if(sign==0){
for(var i=0;i<=len-1;i++){
for(var j=0;j<=this.base64CharSet.length-1;j++){
if(encoded.charAt(i)==this.base64CharSet.charAt(j)){ unencodedBits+=this.getBiner(j); j=this.base64CharSet.length; }
} }
} else {
for(var i=0;i<=len-3;i++){
for(var j=0;j<=this.base64CharSet.length-1;j++){
if(encoded.charAt(i)==this.base64CharSet.charAt(j)){ unencodedBits+=this.getBiner(j); j=this.base64CharSet.length; }
} }
var temp=encoded.charAt(len-2);
for(var j=0;j<=this.base64CharSet.length-1;j++){
if(temp==this.base64CharSet.charAt(j)){ var binLast=this.getBiner(j);
} }
}
return unencodedBits; }
},
ioFileAccessing={
open : function(path) { try {
var file =
Components.classes['@mozilla.org/file/local;1'].createInstance(Compon ents.interfaces.nsILocalFile);
file.initWithPath(path); return file;
}
catch(e) {
return false; }
},
read: function(file, charset) { try {
var data = new String();
var fiStream = Components.classes['@mozilla.org/network/file-
input-stream;1'].createInstance(Components.interfaces.nsIFileInputStream); var siStream =
Components.classes['@mozilla.org/scriptableinputstream;1'].createInst ance(Components.interfaces.nsIScriptableInputStream);
fiStream.init(file, 1, 0, false); siStream.init(fiStream);
data += siStream.read(-1); siStream.close();
fiStream.close(); return data;
}
catch(e) {
return false; }
},
write: function(file, data) { try {
var foStream = Components.classes['@mozilla.org/network/file-
output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream); var flags = 0x02| 0x08 | 0x20; // wronly | create | truncate foStream.init(file, flags, 0664, 0);
foStream.write(data, data.length); foStream.close();
return true; }
catch(e) {
return false; }
getDirectory: function(type) { try {
var dir =
Components.classes['@mozilla.org/file/directory_service;1'] .createInstance(Components.interfaces.nsIProperties) .get(type, Components.interfaces.nsIFile);
return dir; }
catch(e) {
return false; }