IMPLEMENTASI ALGORITMA KRIPTOGRAFI RSA DAN RABIN PADA THREE-PASS PROTOCOL UNTUK PENGAMANAN DATA PADA APLIKASI CHAT BERBASIS ANDROID

A-1

LISTING PROGRAM
1. Program Rabin
package com.januar.tppchat.crypto;
import java.nio.ByteBuffer;
public class Rabin {
public static long Encrypt(long n, long m) {
long cipher = GeneralMath.ModularExponential(m, 2, n);
return cipher;
}
public static long Decrypt(Long cipher, int p, int q){
long[] euclidean = GeneralMath.ExtendedEuclideanAll(p, q);
long Yp = euclidean[1];
long Yq = euclidean[2];
long mp = 0;
long mq = 0;
long n = p * q;
mp = GeneralMath.ModularExponential(cipher, (p+1)/4, p);
mq = GeneralMath.ModularExponential(cipher, (q+1)/4, q);
Long R = GeneralMath.mod((Yp * p * mq) + (Yq * q * mp), n);

Long S = GeneralMath.mod((Yp * p * mq) - (Yq * q * mp), n);
Long T = GeneralMath.mod(-1*(Yp * p * mq) + (Yq * q * mp),
n);
Long U = GeneralMath.mod(-1*(Yp * p * mq) - (Yq * q * mp),
n);
if (checkSimilarity(R) != -1) {
return checkSimilarity(R);
}else if (checkSimilarity(S) != -1) {
return checkSimilarity(S);
}else if (checkSimilarity(T) != -1) {
return checkSimilarity(T);
}else if (checkSimilarity(U) != -1) {
return checkSimilarity(U);
}
return 0;
}
public static long[] DecryptArray(Long cipher, long p, long q){
long[] euclidean = GeneralMath.ExtendedEuclideanAll(p, q);
long Yp = euclidean[1];
long Yq = euclidean[2];

long mp = 0;
long mq = 0;
long n = p * q;
mp = GeneralMath.ModularExponential(cipher, (p+1)/4, p);
mq = GeneralMath.ModularExponential(cipher, (q+1)/4, q);
Long R = GeneralMath.mod((Yp * p * mq) + (Yq * q * mp), n);
Long S = GeneralMath.mod((Yp * p * mq) - (Yq * q * mp), n);
Long T = GeneralMath.mod(-1*(Yp * p * mq) + (Yq * q * mp),

A-2

n);
Long U = GeneralMath.mod(-1*(Yp * p * mq) - (Yq * q * mp),
n);
long[] result = new long[]{R,S,T,U};
return result;
}
public static String Decrypt(int p, int q, byte[] cipherByte) throws
InvalidKeyException {
String plainText = "";

for (int i = 0; i < cipherByte.length / 8; i++) {
byte[] cipher = new byte[4];
byte[] kongruenByte = new byte[4];
for (int j = 0; j < kongruenByte.length; j++) {
cipher[j] = cipherByte[(i*8)+j];
kongruenByte[j] = cipherByte[(i*8+4)+j];
}
int cipherInt = ByteBuffer.wrap(cipher).getInt();
int plainInt = (int)Decrypt((long)cipherInt, p, q);
if (plainInt == 0) {
throw new InvalidKeyException("private key wrong.");
}
String plainBitString = Integer.toString(plainInt, 2);
plainText = plainText +
(char)Integer.parseInt(plainBitString.substring(0,
plainBitString.length() - 8), 2)
+
(char)Integer.parseInt(plainBitString.substring(plainBitString.length
() - 8), 2);
}

return plainText;
}
public static int checkSimilarity(Long p)
{
String binary = Long.toString(p, 2);
if ((binary.length() % 2) == 0) {
if (binary.substring(0, binary.length() /
2).equals(binary.substring(binary.length() /2))) {
return Integer.parseInt(binary.substring(0, binary.length() /2), 2);
}else{
return -1;
}
} else {
return -1;
}
}
}

A-3


2. Program RSA
package com.januar.tppchat.crypto;
import java.math.BigInteger;
import java.util.Random;
public class RSA {
public static long getPublicKey(long totien){
Random random = new Random();
long e = 100 + (long)(random.nextDouble()*(totien - 100));
while (GeneralMath.GCD(totien, e) != 1) {
e = 100 + (long)(random.nextDouble()*(totien - 100));
}
return e;
}
public static long getPrivateKey(long totien, long e){
return GeneralMath.ExtendedEuclidean(totien, e);
}
public static long Encrypt(long m, long e, long n){
//
return GeneralMath.ModularExponential(m, e, n);
BigInteger b_m = new BigInteger(Long.toString(m));

BigInteger b_e = new BigInteger(Long.toString(e));
BigInteger b_n = new BigInteger(Long.toString(n));
BigInteger result = b_m.modPow(b_e,b_n);
return Long.parseLong(result.toString());
}
public static long Decrypt(long c, long d, long n){
//
return GeneralMath.ModularExponential(c, d, n);
BigInteger b_c = new BigInteger(Long.toString(c));
BigInteger b_d = new BigInteger(Long.toString(d));
BigInteger b_n = new BigInteger(Long.toString(n));
BigInteger result = b_c.modPow(b_d,b_n);
return Long.parseLong(result.toString());
}
}

3. Program Sieve of Eratosthenes
package com.januar.tppchat.crypto;
import java.util.ArrayList;
import java.util.List;

import java.util.Random;
public class SieveofEratosthenes {
public static final int MAX = 99999999;
public static List generate(int min, int limit) {
//int limit = 99999999; // Batas maksimum bil. prima yang dicari

A-4

boolean[] bil_asal = new boolean[limit];
for (int i = 0; i < limit; i++) {
bil_asal[i] = true;
}
bil_asal[0] = false; // bilangan 0 bukan bilangan prima
bil_asal[1] = false; // bilangan 1 bukan bilangan prima
// Penerapan algoritma Sieve of Erathosthenes
for (int i = 2; i = min) {
prima.add(i);
}
}
System.out.println("Jumlah bilangan prima antara "+ min +"

sampai " + limit
+ " adalah " + prima.size() + " buah");
return prima;
}
public static List generate() {
return SieveofEratosthenes.generate(2, MAX);
}
public static List generate(int limit) {
return SieveofEratosthenes.generate(2, limit);
}
public static List generateKey() {
List keys = new ArrayList();
List prima = SieveofEratosthenes.generate(100,
10000);
Random random = new Random();
int q = 0;
int temp = random.nextInt(prima.size());
keys.add(prima.get(temp));
do {
temp = random.nextInt(prima.size());

q = prima.get(temp);
} while (keys.get(0) == q);
keys.add(q);
return keys;
}
public static List generateRabinKey() {
List keys = new ArrayList();
List prima = SieveofEratosthenes.generate(100000,
1000000);

A-5

Random random = new Random();
while (keys.size() != 2) {
int temp = random.nextInt(prima.size());
if (prima.get(temp) % 4 == 3) {
if (!keys.contains(prima.get(temp))) {
keys.add(prima.get(temp));
}
}

}
return keys;
}
}

4. Program Three-Pass Protocol
package com.januar.tppchat.crypto;
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
public class ThreePassProtocol {
public static String PassOne(String text, long n) throws
UnsupportedEncodingException {
byte[] cipherByte = new byte[text.length() * 8]; // dikali 8 karena
ukuran tipe data long
int i = 0;
for (char ch : text.toCharArray()) {
int c = (int)ch;
String plaintext = Integer.toString(c, 2);
plaintext = plaintext + plaintext;

long m = Long.parseLong(plaintext, 2);
long enc = Rabin.Encrypt(n, m);
System.arraycopy(ByteBuffer.allocate(8).putLong(enc).array(), 0,
cipherByte, i * 8, 8);
i++;
}
return Base64.encodeToString(cipherByte, Base64.DEFAULT);
}
public static String PassTwo(String text, long e, long n) throws
UnsupportedEncodingException {
byte[] plainByte = Base64.decode(text, Base64.DEFAULT);
byte[] cipherByte = new byte[plainByte.length]; // panjang byte plain
dengan cipher sama
for (int i = 0; i < (plainByte.length / 8); i++) {
byte[] temp = new byte[8];
System.arraycopy(plainByte, i * 8, temp, 0, 8);
long m = ByteBuffer.wrap(temp).getLong();
long enc = RSA.Encrypt(m, e, n);

A-6

System.arraycopy(ByteBuffer.allocate(8).putLong(enc).array(), 0,
cipherByte, i * 8, 8);
}
return Base64.encodeToString(cipherByte, Base64.DEFAULT);
}
public static String PassThree(String text, long p, long q) throws
UnsupportedEncodingException {
byte[] cipherByte = Base64.decode(text, Base64.DEFAULT);
byte[] plainByte = new byte[cipherByte.length * 4]; // setiap satu
bilangan menghasilkan 4 hasil dekripsi
for (int i = 0; i < (cipherByte.length / 8); i++) {
byte[] temp = new byte[8];
System.arraycopy(cipherByte, i * 8, temp, 0, 8);
long c = ByteBuffer.wrap(temp).getLong();
long[] dec = Rabin.DecryptArray(c, p, q);
byte[] decByte = new byte[32];
System.arraycopy(ByteBuffer.allocate(8).putLong(dec[0]).array(), 0,
decByte, 0, 8);
System.arraycopy(ByteBuffer.allocate(8).putLong(dec[1]).array(), 0,
decByte, 8, 8);
System.arraycopy(ByteBuffer.allocate(8).putLong(dec[2]).array(), 0,
decByte, 16, 8);
System.arraycopy(ByteBuffer.allocate(8).putLong(dec[3]).array(), 0,
decByte, 24, 8);
System.arraycopy(decByte, 0, plainByte, (i * 32), 32);
}
return Base64.encodeToString(plainByte, Base64.DEFAULT);
}
public static String DecryptResult(String text, long d, long n) {
String plain = "";
byte[] cipherByte = Base64.decode(text, Base64.DEFAULT);
for (int i = 0; i < (cipherByte.length / 32); i++) {
byte[] temp = new byte[8];
System.arraycopy(cipherByte, i * 32, temp, 0, 8);
long c = ByteBuffer.wrap(temp).getLong();
long c1 = Rabin.checkSimilarity(RSA.Decrypt(c, d, n));
System.arraycopy(cipherByte, (i * 32) + 8, temp, 0, 8);
c = ByteBuffer.wrap(temp).getLong();
long c2 = Rabin.checkSimilarity(RSA.Decrypt(c, d, n));
System.arraycopy(cipherByte, (i * 32) + 16, temp, 0, 8);
c = ByteBuffer.wrap(temp).getLong();
long c3 = Rabin.checkSimilarity(RSA.Decrypt(c, d, n));
System.arraycopy(cipherByte, (i * 32) + 24, temp, 0, 8);
c = ByteBuffer.wrap(temp).getLong();
long c4 = Rabin.checkSimilarity(RSA.Decrypt(c, d, n));
if(c1 != -1){
plain += (char)c1;
}else if(c2 != -1){

A-7

plain += (char)c2;
}else if(c3 != -1){
plain += (char)c3;
}else if(c4 != -1){
plain += (char)c4;
}
}
return plain;
}
}

B-1

CURRICULUM VITAE
DATA PRIBADI
Nama Lengkap

: Januar Andi Halomoan Sirait

Tempat / Tanggal lahir : Medan / 21Januari 1991
Alamat rumah

: Dusun I Kamboja, Laut Dendang
Deli Serdang

Jenis Kelamin

: Laki-Laki

Agama

: Kristen Protestan

Status

: Belum menikah

No. HP

: 085760534549

E-mail

: januar.srt@gmail.com

RIWAYAT PENDIDIKAN FORMAL
1998-2003

: SD BUDI MURNI 7 MEDAN

2003-2006

: SMP BUDI MURNI 4 MEDAN

2006-2009

: SMA NEGERI 7 MEDAN

2009-2012

: POLITEKNIK INFORMATIKA DEL

SEMINAR
2014

: Peserta Seminar Nasional Literasi Informasi (SENARAI)

PENGALAMAN KERJA
2012

: Kerja Praktek di PT. Mandiri Inti Perkasa ,
Jakarta – Kalimantan Timur

2012 - 2016

: Bekerja di PT. Halotec Indonesia, Medan

2016 – sekarang : Bekerja di PT. Infomasi Guna Optima (inGO), Medan