Thursday, November 12, 2009

Solusi Kriptografi dengan Java menggunakan Java Cryptography Extension (JCE)

image
Java itu indah sekali.
Letak indahnya adalah, Anda bisa menyelesaikan hampir semua masalah komputasi, hanya dengan menguasai satu dialek ini saja : Java. Alasan utamanya adalah, Java ada di sistem Desktop (J2SE), Server(J2EE) atau Mobile (J2ME).
Aplikasi yang saya jelaskan ini adalah aplikasi penggunaan JCE (Java Cryptography Extension). Kriptografi tentunya kasus yang rumit, jika ditilik dari teori Matematikanya. Namun, sebagai sebuah produk, kriptografi mudah sekali : gunakanlah JCE, yang merupakan paket ekstensi (bukan standard ya) Java untuk solusi cepat penggunaan kriptografi.
Saya pastekan saja kode utama untuk melakukan enkripsi berikut :




public static String encrypt(String originalText, String password) {
        String enc = "";
        try {
            // cara penggunaan JCE u/ melakukan enkripsi berdasarkan metode enkripsi PBE, yg dipilih (tidak
            // mesti PBEWithMD5AndDES
            PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(METHOD);
            SecretKey secretKey = keyFactory.generateSecret(keySpec);
            PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterationCount);
            cipher = Cipher.getInstance(METHOD);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
            outputArray = originalText.getBytes(encoding);
            cryptedText = new ByteArrayOutputStream();
            CipherOutputStream out = new CipherOutputStream(cryptedText, cipher);
            out.write(outputArray);
            out.flush();
            out.close();
            return cryptedText.toString();
        } catch (IOException ex) {
           …
       }
        return "error";
    }
Sedangkan untuk dekripsi, sebagai berikut :
public static String decrypt(String cryptedText, String password) {
    String dec = "";
    try {
        // convert to byte array
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(METHOD);
        SecretKey secretKey = keyFactory.generateSecret(keySpec);
        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, iterationCount);
        cipher = Cipher.getInstance(METHOD);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec);
        decryptedText = new ByteArrayInputStream(cryptedText.getBytes());
        CipherInputStream in = new CipherInputStream(decryptedText, cipher);
        byte contents = (byte) in.read();
        char c = 82;
        while (contents != -1) {
            fileBytes.add(new Byte(contents));
            c = (char) Integer.parseInt(fileBytes.get(fileBytes.size() - 1) + "");
            dec = dec + c;
            contents = (byte) in.read();
        }
        in.close();
    } catch (IOException ex) {
        Logger.getLogger(Logic.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Logic.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidAlgorithmParameterException ex) {
        Logger.getLogger(Logic.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeySpecException ex) {
        Logger.getLogger(Logic.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Logic.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Logic.class.getName()).log(Level.SEVERE, null, ex);
    }
    return dec;
}

Namun, jika kode tersebut dijalankan, kemungkinan akan terjadi error, karena karakter yang dihasilkannya bukan karakter standar. Untuk mengatasi masalah ini, lakukan perubahan karakter hasil enkripsi atau karakter ciphertext dengan menggunakan Base 64. Contoh ditunjukkan berikut:
public static String safeEncrypt(String plainText,String password){
      return Base64Coder.encodeString(encrypt(plainText, password));
  }
  public static String safeDecrypt(String cryptedText,String password){
      return decrypt(Base64Coder.decodeString(cryptedText), password);
  }
Adapun kode untuk encode adalah sebagai berikut:
public static char[] encode (byte[] in, int iLen) {
   int oDataLen = (iLen*4+2)/3;       // output length without padding
   int oLen = ((iLen+2)/3)*4;         // output length including padding
   char[] out = new char[oLen];
   int ip = 0;
   int op = 0;
   while (ip < iLen) {
      int i0 = in[ip++] & 0xff;
      int i1 = ip < iLen ? in[ip++] & 0xff : 0;
      int i2 = ip < iLen ? in[ip++] & 0xff : 0;
      int o0 = i0 >>> 2;
      int o1 = ((i0 &   3) << 4) | (i1 >>> 4);
      int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
      int o3 = i2 & 0x3F;
      out[op++] = map1[o0];
      out[op++] = map1[o1];
      out[op] = op < oDataLen ? map1[o2] : '='; op++;
      out[op] = op < oDataLen ? map1[o3] : '='; op++; }
   return out;
}
Dengan kode decode juga sebagai berikut:
public static byte[] decode (char[] in) {
   int iLen = in.length;
   if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
   while (iLen > 0 && in[iLen-1] == '=') iLen--;
   int oLen = (iLen*3) / 4;
   byte[] out = new byte[oLen];
   int ip = 0;
   int op = 0;
   while (ip < iLen) {
      int i0 = in[ip++];
      int i1 = in[ip++];
      int i2 = ip < iLen ? in[ip++] : 'A';
      int i3 = ip < iLen ? in[ip++] : 'A';
      if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
         throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
      int b0 = map2[i0];
      int b1 = map2[i1];
      int b2 = map2[i2];
      int b3 = map2[i3];
      if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
         throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
      int o0 = ( b0       <<2) | (b1>>>4);
      int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
      int o2 = ((b2 &   3)<<6) |  b3;
      out[op++] = (byte)o0;
      if (op<oLen) out[op++] = (byte)o1;
      if (op<oLen) out[op++] = (byte)o2; }
   return out;
}
Oke, semoga bermanfaat!
NB:
  • Kriptografi dengan Platform pemrograman yang lain saya belum lihat, tepatnya dengan VS.NET. Mungkin juga sudah ada standar yang umum ya?

20 comments:

Anonymous said...

Lumaya sulit

Eko said...

:) ga sesulit yg dibayangkan kok. Download aja programnya, dan koding!

Nuhajat said...

Mantap!!!! Subhannallah,...

Anonymous said...

mas bisa kasih penjelasan tentang algoritma nya ngak??program nya uda jalan tapi ngak tau darimana dapet hasil enkripsi tuh,,makasih mas......

Anonymous said...

mas bisa kasih penjelasan tentang algoritma nya ngak??program nya uda jalan tapi ngak tau darimana dapet hasil enkripsi tuh,,makasih mas......

Anonymous said...

mas kasih tau tentana algoritma nya dunk.. mkasih.

Eko said...

nah, sudah jalan?
kalau sudah bagus2...
hihi

algoritmanya, kalau di JCE, enggak relevan : kau pakai aja. gitu
pelajari aja aristektur JCE, ntar itu sudah cukup untuk pakai semua algoritma, tanpa tau kerja algoritmanya
simpel kan?

* kalau ttg algoritmanya itu sendiri, pelajari sendiri, bukan di JCE ya. :P

Anonymous said...

tuh pakai md5 ya mas..
tuh algoritma cuma di panggil ya bukan kita yang bikin.

Eko said...

hiya betul :p
oh, keecuali kita jadi provider dari JCE. wah, itu tuh, bisa dipelajari.
tergantung tarif. hihi

Anonymous said...

sori mas kalo cerewet
kalo make algoritma tree mas tau nga??implementasi ke java kayak apa??

Eko said...

hehe.cerewet sih gpp.tapi ini sy ngomong sama sapa sih? :D

belum pernah coba dik, tapi kalau tau algoritmanya, dan itu sudah baku, mudah saja

Ivan Jaya said...

mas, bagaimana dengan kriptografi md5 untuk mendapatkan hash suatu file (itu tu seperti download file baru di ceck kode md5 nya) ?

butuh banget nih mas buat belajar kripto.

Thanks.

Balas ke email saya yah: jayaivan@gmail.com

ازلينا ااحمد‬‎ said...

Adaka boleh JCE digunakan di J2ME?

Eko said...

bisa. coba search "bouncy castle jce"
bs dipakai di j2me

Ahsanfile Project said...

Mas, muncul warning kalau Base64 adalah property sun yang katanya tidak ada para release berikutnya...

gimana mengatasi ini

warning: sun.misc.BASE64Encoder is Sun proprietary API and may be removed in a future release
private sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();

Eko said...

gpp. :)
warning aja kok. kalau error, baru :)

sejauh itu, aplikasimu dah rampung kan?

sukses!

Auliya Iskandar Muhammad Noer said...

instan aja mas... ribet tu orang bodoh kaya' gw....
mana musti belajar dulu, ....

ndahssindah said...

mas, boleh minta source code kriptografi nya ???
ada tugas nih deadline,, mohon bantuannya ya mas plis plisss....

indrimuliasari said...

Maaf saya mau nanya, kalau kriptografi contoh dlm kehidupan sehari2nya untuk apa ya? Terima kasih

Anonymous said...

Mas link source code-nya ko udah dihapus ya? :)