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"
plaintext, _ := ioutil.ReadFile("D:/matang.png")
key, _ := ioutil.ReadFile("D:/key.txt")
1111111111111111
import ( "crypto/aes" "crypto/cipher" "crypto/rand" "fmt" "io" "io/ioutil" )
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 }
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"
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