Post

Practical AES Encryption, How to Decrypt It?

Practical AES Encryption, How to Decrypt It?

Motivasi saya membuat artikel ini adalah karena pada awalnya saya merasa bahwa belajar enkripsi memang sangat membosankan. Banyak artikel lebih menekankan konsep teoritis, tetapi kurang praktis dan teknis. Di sisi lain, saya menyadari bahwa enkripsi AES (Advanced Encryption Standard) tidaklah semembosankan itu. Sebagai seorang pentester, saya juga menemukan banyak aplikasi, khususnya aplikasi mobile, yang menggunakan mekanisme enkripsi AES pada data HTTP request sebelum dikirimkan ke API. Oleh karena itu, saya rasa dengan mempelajari AES ini dapat menjadi skillset tambahan yang berguna untuk melakukan pentest.

Agar tidak terlalu bertele-tele, berikut ini adalah poin-poin yang sudah saya rangkum agar lebih mudah dipahami.

Symmetric Encryption

Symmetric Encryption adalah sebuah metode enkripsi di mana key yang digunakan untuk proses encrypt dan decrypt itu hanya menggunakan satu key (key yang sama). Jadi untuk mempelajari AES ini pada dasarnya tidak terlalu sulit.

Berbeda dengan Asymmetric Encryption, yang menggunakan dua key yang berbeda, public key untuk encrypt dan private key decrypt (contohnya RSA).

Symmetric Encryption vs Asymmetric Encryption

AES Output Encoding

Hasil enkripsi (output) atau (biasa disebut) ciphertext itu biasanya dibungkus dalam bentuk encoding, yang paling umum digunakan yaitu:

  1. Base64
  2. Hex

Kenapa harus di-encode setelah selesai dienkripsi?

Karena kalau tidak di-encode maka bentuk aslinya adalah karakter-karakter yang tidak karuan bentuknya dan sangat riskan untuk pertukaran data karena beberapa protokol tidak akan mengenali karakter-karakter tersebut.

AES without Encoding

AES Key Length

Panjang kunci (Key Length) dalam AES hanya ada tiga varian:

  • 16 byte (128 bit)
  • 24 byte (192 bit)
  • 32 byte (256 bit)

Panjang kunci menentukan tingkat keamanan AES (semakin panjang kuncinya, semakin sulit untuk dilakukan brute force).

Mungkin kalian pernah dengar tentang AES-128, AES-192, dan AES-256. Nah! Pada dasarnya itu hanya mengacu pada panjang kunci yang digunakan.

Contoh Key pada AES-128:

1
key = b'KeepItSecret_16_'

Contoh Key pada AES-192:

1
key = b'Key_Dengan_Panjang__24__'

Contoh Key pada AES-256:

1
key = b'_Str0ng3st_AES_KeY_1s__32_bytes!'

AES Operation Mode

Mode atau mode operasi pada AES ini yang nantinya akan berperan penting untuk menentukan bagaimana tiap blok (per-byte atau perhurufnya) akan diproses.

Pada dasarnya, terdapat banyak mode yang bisa digunakan pada AES. Seperti CTR, CFB, GCM dan lain-lain. Namun, di sini yang akan kita bahas itu hanya CBC dan ECB saja agar tidak terlalu overwhelming.

Perbedaan yang mencolok pada kedua mode tersebut adalah penggunaan IV (Initialization Vector). Yang di mana CBC itu memerlukan IV, sedangkan ECB tidak.

IV ini bisa kita analogikan sebagai kunci kedua (second key) untuk tambahan keamanan

ECB (Electronic Codebook)

Setiap blok plaintext (per-byte atau perhuruf), akan langsung diproses begitu saja. Pola hasil enkripsi akan terlihat, karena blok dari plaintext (yang sama) akan menghasilkan blok ciphertext yang sama (juga).

CBC (Cipher Block Chaining)

Berbeda dengan ECB, pada CBC blok pertama akan di-encrypt menggunakan IV (Initialization Vector). Lalu, setiap blok plaintext-nya (yang belum dienkripsi) akan di-XOR dengan blok ciphertext sebelumnya, sehingga akan menghasilkan pola enkripsi yang tidak terlihat (karena acak).

Dengan penjelasan tersebut, maka kita dapat menyimpulkan bahwa mode ECB itu lebih lemah dari mode CBC dan mode-mode lainnya.

Initialization Vector (IV)

Initialization Vector (IV) bisa kita analogikan sebagai kunci kedua (second key). Namun, lebih tepatnya lagi itu seperti salt pada konsep hashing. Yang di mana akan menghadirkan ketidakpastian karena akan menciptakan pola acak pada tiap-tiap blok yang terenkripsi.

Karakter pada IV memiliki panjang yang pasti, yaitu 16 byte dan tidak ada varian lain seperti key.

Sebagai contoh:

1
init_vector = b'IV_would_be___16'

Cara mengenali AES atau bukan?

Enkripsi AES akan selalu memproses data dalam kelipatan 16 byte. Jadi, meskipun data aslinya tidak berkelipatan 16 byte, hasil enkripsinya akan tetap menjadi kelipatan 16 byte. Selain itu, ukuran key-nya juga tidak memengaruhi ukuran data yang sudah diproses, di mana hasilnya akan tetap menjadi kelipatan 16 byte, apa pun bentuknya.

Sebagai contoh di sini, untuk menentukan AES atau bukan dapat menggunakan rumus cipher_bytes % 16, seperti script di bawah ini:

1
2
3
4
5
6
7
8
9
10
11
12
import base64

def is_AES(ciphertext_bytes):
    if len(ciphertext_bytes) % 16 == 0:
    	return True
    else:
    	return False

base64_ciphertext = "Tra+6tlhtCU9PM7cKWM2QcK3ag22lxTivZmRdd9FZVCRgeM79lWVWbWAGevO3HoeTPV/rI5EabHM+TdOBvxkc/51qLQ0qUh4rlbELka4yKQ="
ciphertext_bytes = base64.b64decode(base64_ciphertext)

print('Byte Length {byte_length}, Is it AES? {is_AES}'.format(byte_length=len(ciphertext_bytes), is_AES=is_AES(ciphertext_bytes)))

Output yang dihasilkan dari script-nya adalah Byte Length 80, Is it AES? True. Karena 80 itu masih dalam kelipatan 16, jadi dapat dipastikan (besar kemungkinan) ciphertext di atas dienkripsi menggunakan AES.

Padding

Jika ukuran data tidak dalam kelipatan 16 byte, maka tugas padding di sini akan menambahkan blok terakhir agar mencapai ukuran yang sesuai (kelipatan 16).

Misal, saya akan mencoba untuk mengenkripsi kata ENCRYPT_ME yang di mana kata tersebut hanya berukuran 10 bytes (atau 10 karakter).

12345678910111213141516
ENCRYPT_ME      

Nah! Inilah fungsi padding, yang di mana akan mengisi sisa bloknya yang kosong (dari 11 sampai 16). Sehingga setelah proses enkripsinya selesai maka hasilnya akan tetap 16 bytes.

12345678910111213141516
0x280x450x8b0xed0xbd0x210xb00x7d0x470x820xd00x560x360xcb0x5a0xff
This post is licensed under CC BY 4.0 by the author.