Enkripsi File dengan Kriptografi AES

By | April 16, 2022
Print Friendly, PDF & Email
1,744 Views

Pencurian data yang semakin marak tentu sangat mengkhawatirkan karena banyak data sensitif yang terpublish dengan mudah, apalagi saat ini sudah banyak sekali aplikasi cloud seperti google drive, one drive, dropbox yang memberikan hosting file gratis dengan kapasitas cukup besar. Tapi walaupun begitu, saya termasuk orang konsertatif sehingga tidak begitu saja menyimpan file-file penting dihosting tersebut.

Biasanya saya melakukan backup data seperti foto WA di hardisk serta memisahkan foto yang mengandung wajah dan bukan untuk menghemat penyimpanan. Salah satu cara mengamankan file digital yang paling mudah dilakukan yaitu menggunakan teknik enkripsi. Saya pernah bahas Enkripsi File dengan Kriptografi AES menggunakan bahasa java https://softscients.com/2022/03/27/amankan-data-dengan-enkripsi/. Saya juga pernah menggunakan C/C++ tapi koq rumit sekali penggunaannya library seperti openssl/crypto++. Maka pilihannya pada bahasa go languange. Kenapa go lang? karena bisa build nativ  di windows jadi nggak kayak java/python yang butuh Virtual machine nya.

Setelah saya searching go lang untuk enkripsi ternyata ada package bawaan nya juga, jadi nggak perlu pihak ketiga. Hal ini wajar saja karena go languange sebenarnya banyak digunakan untuk membuat aplikasi berbasis server. Untuk algoritma yang kita pilih yaitu AES-16 bit, referensi yang bisa kita gunakan yaitu https://levelup.gitconnected.com/a-short-guide-to-encryption-using-go-da97c928259f

Nanti juga dibahas, bagaimana sebuah file tersebut sudah di enkripsi? sehingga tidak terjadi double enkripsi yang akan menyulitkan kita dalam proses dekripsi

Package Kriptografi

Seperti yang dikemukakan sebelumnya bahwa enkripsi file dengan kriptografi AES di Go Languange sangat mudah, karena sudah ada package nya. Berikut package yang kalian bisa gunakan

"crypto/aes"

"crypto/cipher"

"crypto/rand"
Cara kerja untuk Enkripsi File dengan Kriptografi AES yaitu menggunakan tipe data byte. Jadi setiap data nantinya dibaca sebagai mode biner. Perhatikan kode berikut untuk membaca sebuah file image
plaintext, _ := ioutil.ReadFile("D:/matang.png")
variabel plaintext merupakan  byte , sedangkan untuk membuat key, kita bisa menggunakan *.txt yang berisi 16 karakter
key, _ := ioutil.ReadFile("D:/key.txt")
isi file key.txt sebenarnya bisa kalian tulis macam2 karakter, tapi wajib 16 karakter jumlahnya! Misalkan saya isi karakter 1 berikut
1111111111111111
Berikut kode yang digunakan untuk Enkripsi File dengan Kriptografi AES yang dimulai dari package yang nanti kita gunakan
import ( "crypto/aes"
 "crypto/cipher" 
"crypto/rand" 
"fmt" 
"io"
 "io/ioutil" )
Sedangkan function enkripsi dan dekripsi yaitu
func encrypt(plainstring, keystring []byte) []byte {
   // Byte array of the string
   plaintext := plainstring //[]byte(plainstring)

   // Key
   key := keystring //[]byte(keystring)

   // Create the AES cipher
   block, err := aes.NewCipher(key)
   if err != nil {
      panic(err)
   }

   // Empty array of 16 + plaintext length
   // Include the IV at the beginning
   ciphertext := make([]byte, aes.BlockSize+len(plaintext))

   // Slice of first 16 bytes
   iv := ciphertext[:aes.BlockSize]

   // Write 16 rand bytes to fill iv
   if _, err := io.ReadFull(rand.Reader, iv); err != nil {
      panic(err)
   }

   // Return an encrypted stream
   stream := cipher.NewCFBEncrypter(block, iv)

   // Encrypt bytes from plaintext to ciphertext
   stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

   return ciphertext
}
Setelah kita buat kode diatas, kita terapkan saja kedalam func main sebagai contoh kita akan melakukan enkripsi file gambar dengan format *.png dengan file raw yaitu matang.png maka hasil enkripsi yaitu matang2.png (nanti hasilnya tidak bisa dibaca oleh image viewer karena rusak formatnya)
var file1 string = "D:/matang.png"
var file2 string = "D:/matang2.png"
var file3 string = "D:/matang3.png"
var file_kunci string = "D:/key.txt"
untuk mengembalikan awal lagi maka file matang2.png dibaca lagi untuk dilakukan dekripsi yaitu matang3.png
plaintext, _ := ioutil.ReadFile(file1)

key, _ := ioutil.ReadFile(file_kunci)

//lakukan enkripsi
byte_enkrip := encrypt(plaintext, key)
ioutil.WriteFile(file2, byte_enkrip, 777)

//lakukan dekripsi
byte_dekrip, _ := ioutil.ReadFile(file2)
var byte_dekrip2 []byte = decrypt(byte_dekrip, key)
ioutil.WriteFile(file3, byte_dekrip2, 777)

Proses diatas sangat cepat sekali, ketika kode diatas saya build ke exe ukuran file aplikasi tersebut cukup besar tapi bisa kurangi koq dengan UPX

UPX comes with ABSOLUTELY NO WARRANTY; for details visit https://upx.github.io
PS D:\upx-3.96-win64> .\upx -9 -f main.exe -o main2.exe
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2020
UPX 3.96w       Markus Oberhumer, Laszlo Molnar & John Reiser   Jan 23rd 2020

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
   2116608 ->   1219584   57.62%    win64/pe     main2.exe

Dari semual 2116608 byte mejiad 1219584 byte atau berkurang hampir 60% tanpa ada masalah karena go lang bisa di compile ke native application seperti exe di Windows sehingga aman2 saja ketika dijalakan dan tanpa membutuhkan virtual machin.

Nampaknya untuk kegiatan sehari-hari lebih bagus menggunakan Golang saja daripada C/C++ yang ribet. Oiya untuk Enkripsi File dengan Kriptografi AES ada PR yang mungkin bisa kalian kerjakan, yaitu memberikan flag pada sebuah file bahwa file tersebut sudah dilakukan enkripsi, biasanya sih cara mudahnya yaitu mengubah byte awal dengan flag yang kita buat! misalkan 10 byte awal akan diganti karakternya dengan karakter tertentu. Sehingga sebelum proses enkripsi dimulai, maka dilakukan checking flag apakah sudah di enkripsi atau belum. Jika belum maka akan dilaklukan enkripsi file nya. Karena akan repot kalau terjadi enkripsi berkali-kali apalagi kalau key nya lupa! akan sangat susah sekali / bahkan tidak mungkin bisa kembali lagi file tersebut ke format aslinya!

Kode lengkapnya

https://github.com/mulkan/golang-enkripsi-aes

Cara Menambahkan sebuah flag pada file agar tidak terjadi double enkripsi!

Konsep ini digunakan untuk memberikan sebuah tanda pada file, apakah file tersebut sudah dilakukan enkripsi? kalau sudah jangan lakukan enkripsi lagi! Cara yang paling mudah kita akan memberikan sebuah array byte sebanyak 10 dengan value 100 (bebas saja sih kalian menggunakan berapa jumlah dan value nya).

const JUMLAH_HEADING int = 10
const NILAI_HEADING byte = 100

Nah ada type data di golang dengan nama slice atau dalam bahasa python/java itu namanya List() karena bisa di append(). Oiya 100 itu dalam ASCII adalah huruf d kecil. Jadi setelah proses enkripsi selesai maka akan ditambah heading tersebut sebagai penanda bahwa file nya telah di enkripsi. Pas dibuka dengan notepad pasti ada 10 karakter huruf d diawal. Karena heading tersebut tidak dilakukan enkripsi maka akan sangat mudah dikenali jika nantinya sebelum melakukan dekripsi/enkripsi dengan cara mengecek 10 karakter pertama, apakah huruf d semuanya?

Agar lebih mudah, saya berikan function nya

func AddHeading(b []byte) []byte {
   /*
      untuk menambahkan byte sebanyak JUMLAH_HEADING
   */
   var a [JUMLAH_HEADING]byte
   for i := 0; i < JUMLAH_HEADING; i++ {
      a[i] = NILAI_HEADING
   }
   slice1 := a[:]                      //jadikan slice
   slice2 := b[:]                      //jadikan slice
   slice3 := append(slice1, slice2...) //lakukan append
   return []byte(slice3)               //balikan lagi ke array
}

Sedangkan untuk proses checking dengan function berikut yaitu dengan cara melakukan sum() bila sum() tersebut == JUMLAH_HEADING * NILAI_HEADING maka dipastikan file tersebut berada dalam mode enkripsi

func CekHeading(a []byte) bool {
   var batas int = JUMLAH_HEADING * int(NILAI_HEADING)
   var total int = 0
   for i := 0; i < JUMLAH_HEADING; i++ {
      total = total + int(a[i])
   }
   var cek bool = false
   if total == batas {
      cek = true
   }
   return cek
}

Kode sebelumnya kita perbaiki lagi agar bisa digunakan dalam mode CLI, saya telah membuat aplikasi berbasis CLI sebagai berikut yaitu aes.exe

.\aes.exe -run 1 -input "D:/sawit.jpg" -output "D:/sawit.jpg" -key "D:/key2.txt"

menggunakan 3 perintah argument input yaitu

  • -run bisa dipilih 1: enkripsi dan 2: dekripsi
  • -input  dan -output merupakan lokasi file yang akan di proses, bila nama file nya sama! maka akan dilakukan overwrite sehingga file yang ada saat ini dalam mode enkripsi
  • -key merupakan file plain text berisi 16 karakter sebagai kunci (wajib 16 karakter!) karena nanti ada pengecekan

Jadi misalkan file1.docx sudah dilakukan enkripsi dan tidak sengaja melakukan enkripsi lagi akan memberikan pesan

Maaf, file sudah dilakukan enkripsi!

sehingga mencegah double enkripsi berkali-kali, karena didalamnya sudah ada heading seperti berikut (ada 10 karakter d) jika dibuka menggunakan notepad/hexa editor

dddddddddd!ϱŠ_,²aÒ%GƒPÛt¡PÀ±3jk£ôÚõٝ°Ba3Ƙø´ÿüf×¥[

Kode yang saya buat cukup panjang, jadi biar tidak bentrok dengan sebelumnya saya buat project lagi di github golang-enkripsi-aes-flag, kalian bisa lihat source code di

https://github.com/mulkan/golang-enkripsi-aes-flag

Bagaimana menurut kalian Enkripsi File dengan Kriptografi AES?

Jauh lebih efektif bukan? untuk memberikan flag pada setiap file yang sudah dilakukan enkripsi jadi kalian tidak perlu kuatir terjadi proses enkripsi file berkali-kali yang akan menyulitkan proses dekripsi nantinya.

Mengenai karakter d kecil itu saya pilih karena suka saja, kalian bebas kok memilih karakter sebagai heading / flag nya

ref:

https://github.com/dyahm78/aes/blob/master/implementasi.cpp

https://kekayan.medium.com/encrypt-files-using-aes-with-openssl-dabb86d5b748

2 thoughts on “Enkripsi File dengan Kriptografi AES

  1. Pingback: trustbet

Leave a Reply