HTTP Client Side Encryption

Begitu banyak website yang pada hakikatnya melayani data-data penting pengguna, namun masih belum terlindungi dengan HTTPS, sebutlah User ID dan Password, se-tidak penting-nya pun User ID dan Password tersebut, namun tidak sedikit orang yang menggunakan User ID bahkan Password yang sama untuk accountnya di website yang lain. Jika demikian kenyataannya, tentulah para eavesdroppers bisa dengan mudah mencoba-coba memasuki account-account yang dimiliki orang tersebut di dunia maya.

Post kali ini saya mencoba meng’akal’i hal tersebut dengan penggunaan metode enkripsi disisi klien dengan RSA yang menggunakan javascript, teori mengenai RSA bisa dibaca di http://id.wikipedia.org/wiki/RSA. Dengan pemrograman Java, RSA sederhana dapat kita buat dengan menggunakan fungsi modpow(BigInteger exponent, BigInteger modulus) yang ada di class java.math.BigInteger seperti ini:

public byte[] encrypt(BigInteger m, BigInteger e, byte[] message){
   BigInteger cipher=new BigInteger(message);
   BigInteger result=cipher.modPow(e,m);
   return result.toByteArray();
}

public  byte[] decrypt(BigInteger m, BigInteger d, byte[] message){
   BigInteger plain=new BigInteger(message);
   BigInteger result=plain.modPow(d,m);
   return result.toByteArray();
}

dimana m, d dan e bisa kita bangkitkan dengan menggunakan java.security.SecureRandom dengan bantuan key pair generator seperti ini :

public static final BigInteger E17=BigInteger.valueOf(17);   // common value
private static final int SIZE=1024;   // key size
private static final int CERTAINTY=80;   //probabilitas BigInteger baru = 1 – 1/2certainty
private static final int HALF=512;   // Half the key size

public RSAKeyPair(SecureRandom sr){
   Thread t=Thread.currentThread();
   boolean doneD=false;
   while(!doneD){
      P=new BigInteger(HALF,CERTAINTY,sr);
      if(t.isInterrupted())
      return;
      Q=new BigInteger(HALF,CERTAINTY,sr);
      if(t.isInterrupted())
      return;
      M=P.multiply(Q);
      while (M.bitLength()!=SIZE){
         if(t.isInterrupted())
            return;
         if(P.compareTo(Q)==-1)
         P=Q;
         Q=new BigInteger(HALF,CERTAINTY,sr);
         M=P.multiply(Q);
      }

      BigInteger p_1=P.subtract(BigInteger.ONE);
      BigInteger q_1=Q.subtract(BigInteger.ONE);
      BigInteger p_1q_1=p_1.multiply(q_1);
      try{
         D=E17.modInverse(p_1q_1);
         doneD=true;
         DP = D.remainder(p_1);
         DQ= D.remainder(q_1);
         QInvP=Q.modInverse(P);
      } catch (ArithmeticException ae){
         doneD=false;
      }
   }
}
Sebelum terlalu jauh dengan RSA menggunakan Java, kembali kepada judul post, key generator diatas dapat dimanfaatkan untuk penggunaan RSA di sisi client, dengan javascript tentunya, tak perlu susah membuat programnya, karena dengan google, kita bisa menemukan beberapa program RSA untuk javascript yang sudah dioptimasi oleh para pakarnya, contoh disini digunakan program buatan Dave Shapiro dari http://www.ohdave.com/rsa/ yang sudah diedit sedikit dan bisa di-download disini. Pada file index.html, di bagian :
function createKey() {
   setMaxDigits(130);
   key = new RSAKeyPair(
      "10001",
      "8e9912….91464fba23d0d965086277a161",
      "a52619….074eafd036a5eb83359d2a698d3"
   );
}
adalah function yang digunakan untuk membuat RSAKeyPair dimana parameter yang dibutuhkan adalah e, d dan m, yang tentunya bisa kita buat terlebih dahulu di sisi server seperti contoh diatas (untuk server yang menggunakan java) kemudian ditulis ke element html yang dapat dibaca oleh javascript.
Nb:
Variabel d tidak perlu ditulis ke elemen html jika RSA javascript hanya digunakan untuk keperluan enkripsi, karna ini justru jadi menggagalkan tujuan dari enkripsi. Format e, d dan m dalam bentuk hex atau dari class java.math.BigInteger bisa langsung ditulis dengan E.toString(16), dimana 16 adalah radix yang digunakan untuk bilangan hexadecimal.