Data Encryption Application (Part 1)

Data Security Opening

As engineers, we must make data security a top priority, especially with sensitive user data being a prime target for hackers. Personal data such as identification numbers, email addresses, and phone numbers are particularly vulnerable to attacks. To protect this data, it is crucial that we do not store it in plaintext format. Instead, we should first encrypt the data before storing it in the database. This approach ensures that even if the data is compromised, hackers will not be able to access the sensitive information.

There are two types of data that we need to manage:

  1. Data that we do not need to know its original form, such as passwords. When it comes to user passwords, we only need to compare the hashed result of the user’s input with the data stored in the database.
  2. Data that we need to know its original information, such as identification numbers, email addresses, social security numbers, and so on.

By understanding the above goals, we can choose the appropriate way to secure data, whether by using Encoding, Encryption, or Hashing. Let’s discuss the differences between these three methods.

Encoding

Encoding is the process of changing data into another format using a specific algorithm. The algorithm used is widely known, so to restore the data to its original form, we only need to use the same algorithm. There is no need to use a key when decoding.

Some commonly used encoding algorithms are ASCII, Unicode, URL Encoding, Base64, etc. The most commonly used algorithm is Base64.

Encryption

Encryption is the process of scrambling readable data into unreadable text, also known as ciphertext. During the encryption process, cryptographic keys are required. As long as third parties or attackers do not have the cryptographic key, the ciphertext cannot be decrypted, ensuring that the stored value remains secure.

There are two types of encryption: symmetric encryption and asymmetric encryption.

A. Symmetric Encryption

Symmetric Encryption is encryption that uses only one key for both encryption and decryption. Therefore, the sender who encrypts the data must provide the key to the person who will decrypt it. Some commonly used algorithms for symmetric encryption are Caesar, Blowfish, and Advanced Encryption Standard or AES.

B. Asymmetric Encryption

For this type of encryption, two different related keys are required, called public and private keys. These two keys have different functions, with the public key used for encryption and the private key used for decryption. An example of an algorithm used for asymmetric encryption is the Rivest-Shamir-Adleman (RSA) algorithm.

Hashing

Unlike encoding and encryption, where the initial value can be restored, any plaintext data that is hashed cannot be restored to its original value. This is because hashing is known as a one-way function. Examples of algorithms used for hashing include MD5, SHA-1, SHA-2, SHA-3, RIPEMD-160, NTLM, and LANMAN.

Data Security Techniques

We can use encryption to ensure data security. Encryption requires an algorithm, key, and value to create ciphertext.

It is recommended not to store the key used for encryption in a single server. We can use Key Management Services (KMS) to store the key. Examples of KMS that we can use include Vault, AWS KMS, and GCP KMS.

I will try to write about my experience to rewrite this rails library https://github.com/ankane/lockbox to go language version.

In general, the steps to secure data (encrypt) are as follows:

  1. Input the data into the application.
  2. Generate a random key.
  3. Encrypt the generated random key using a KMS key and save it as an encrypted_kms_key.
  4. Encrypt the user input using the unencrypted random key and save it as ciphertext.
  5. To facilitate searching, the final step is to create a blind index from the user-inputted value.

This process to encrypt data

For the process of decrypting data:

  1. We need to decrypt the encrypted_kms_key to get the random key in plain text.
  2. After successfully obtaining the random key, we can decrypt the ciphertext using the random key. The final result will be the plain text input from the user.

Let’s create a sample application in Go. In this case, we will be using AWS KMS. Here, we will create a simple library as an example to make this application work.

First, let’s create a struct that will function for decrypting and encrypting.

type Kms interface {
Decrypt(ciphertext string, encryptionContext map[string]*string) (plainText []byte, err error)
Encrypt(message []byte, encryptionContext map[string]*string) (ciphertext string, err error)
}

Let’s break down the code above. It defines an interface called KmsAws with two methods: Decrypt() and Encrypt().

The Decrypt() method takes ciphertext and encryptionContext as input, and returns the plainText response as a byte array ([]byte). The Encrypt() method takes a message, which is the plaintext to be encrypted in the form of []byte, and encryptionContext as input. The output of this function is a string of ciphertext.

The KmsAws interface is used to perform encryption and decryption operations on data using the Key Management Service (KMS) in AWS (Amazon Web Services).

Next, we create a struct to implement the above interface.

type kmsAwsCtx struct {
Session *session.Session
SvcKms *kms.KMS
KmsKeyID string
}

type KmsAwsConfig struct {
AwsAccessKeyID string
AwsSecretAccessKey string
KmsKeyID string
Region string
}

The implementation of the interface is done in the kmsAwsCtx structure that stores the configuration and status of KMS. kmsAwsCtx consists of three fields, namely Session which represents the AWS session, SvcKms which represents the KMS service, and KmsKeyID which represents the ID of the KMS key to be used.

We also need to add the required configuration to create the session that we will use to encrypt and decrypt on the AWS service. This line defines the KmsAwsConfig structure that stores the configuration required to create an kmsAwsCtx instance. The stored configuration includes AwsAccessKeyID, AwsSecretAccessKey, KmsKeyID, and Region.

Then, we will create a function that implements the Kms interface with the following code:

func NewKmsAws(config *KmsAwsConfig) (Kms, error) {
kmsAws := kmsAwsCtx{}
var err error

kmsAws.Session, err = session.NewSession(&aws.Config{
Region: aws.String(config.Region),
Credentials: credentials.NewStaticCredentials(config.AwsAccessKeyID, config.AwsSecretAccessKey, ""),
})
if err != nil {
fmt.Println(err.Error())
return nil, err
}

kmsAws.SvcKms = kms.New(kmsAws.Session)
kmsAws.KmsKeyID = config.KmsKeyID
return &kmsAws, nil
}

The following code defines the KmsAws interface with two methods: Decrypt() and Encrypt(). The Decrypt() method takes in a ciphertext and an encryptionContext as input, and returns the plaintext response as a byte slice. The Encrypt() method takes in a message, which is the plaintext to be encrypted as a byte slice, as well as an encryptionContext for providing additional parameters during encryption. The output of this method is a ciphertext string. The KmsAws interface is used for encrypting and decrypting data using the Key Management Service (KMS) on AWS.

The interface is then implemented in the kmsAwsCtx struct, which stores the KMS configuration and status. kmsAwsCtx has three fields: Session, which represents the AWS session, SvcKms, which represents the KMS service, and KmsKeyID, which represents the ID of the KMS key to be used.

The code also includes the configuration needed to create the session that will be used to perform encryption and decryption on the AWS service. The KmsAwsConfig struct is defined to store the necessary configuration for creating an instance of kmsAwsCtx. The stored configuration includes AwsAccessKeyID, AwsSecretAccessKey, KmsKeyID, and Region.

Finally, a function is created to implement the KmsAws interface. The NewKmsAws() function takes a KmsAwsConfig parameter containing AWS configuration details such as AwsAccessKeyID, AwsSecretAccessKey, KmsKeyID, and Region. Within the function, an instance of kmsAwsCtx is created using the provided configuration, and an AWS session is created using aws.Config and session.NewSession(). Then, an instance of the KMS service is created using kms.New() and the provided configuration.

Finally, the implementation for the Decrypt() and Encrypt() methods are added to the code.

func (c *kmsAwsCtx) Decrypt(chipperText string, encryptionContext map[string]*string) (plainText []byte, err error) {
chipperTextArr := strings.Split(chipperText, `:`)
if len(chipperTextArr) < 2 {
return nil, errors.New(`Invalid Chippertext`)
}

chipperText = chipperTextArr[1]
ciphertextBlob, err := base64.StdEncoding.DecodeString(chipperText)
if err != nil {
fmt.Println(err.Error())
return nil, err
}

inputDecrypt := &kms.DecryptInput{
CiphertextBlob: ciphertextBlob,
EncryptionContext: encryptionContext,
}

respDecrypt, err := c.SvcKms.Decrypt(inputDecrypt)
if err != nil {
fmt.Println(err)
return nil, err
}

return respDecrypt.Plaintext, nil
}

In the Decrypt() method, it is used to perform decryption on a ciphertext. This ciphertext must have the format v1:base64-encoded-ciphertext. In this method, the given ciphertext will be decoded from base64, then used to call the Decrypt() function from the KMS service with the parameters CiphertextBlob and EncryptionContext. The result of the Decrypt() function is plaintext that will be returned.

func (c *kmsAwsCtx) Encrypt(message []byte, encryptionContext map[string]*string) (cipherText string, err error) {
inputEncrypt := &kms.EncryptInput{
KeyId: aws.String(c.KmsKeyID),
Plaintext: []byte(message),
EncryptionContext: encryptionContext,
}

respEncrypt, err := c.SvcKms.Encrypt(inputEncrypt)
if err != nil {
return ``, err
}

dst := make([]byte, base64.StdEncoding.EncodedLen(len(respEncrypt.CiphertextBlob)))
base64.StdEncoding.Encode(dst, respEncrypt.CiphertextBlob)

cipherText = `v1:` + string(dst)
return cipherText, nil
}

The Encrypt() method is used to encrypt a plaintext. In this method, the plaintext provided will be encrypted using the Encrypt() function from the KMS service with parameters KeyId, Plaintext, and EncryptionContext. The result of the Encrypt() function is ciphertext which is then encoded in the v1:base64-encoded-ciphertext format and returned.

Gotcha, that library can use to decrypt ciphertext from rails version, and vice versa, you can decrypt on golang and encrypt with rails version as long the configuration is similar between rails and go.

we have created a sample how to use the Key Management Service (KMS) from Amazon Web Services (AWS) to encrypt and decrypt data.

Overall, this sample application demonstrates how to use the KMS service from AWS to protect sensitive data by encrypting and decrypting it using a secure key.

In the next part, I will give an example about implementation this library and writing about generate random key on golang version.

Binary Search dan Implementasi pada golang

Dalam pencarian sebuah data, ada pendekatan yang bisa kita lakukan. Salah satunya menggunakan algoritma binary search. Binary Search merupakan pencarian nilai (x), pada sebuah kelompok data yang sudah diurutkan terlebih dahulu.

Dalam notasi Big 0, Linier search memiliki time complexity O(n). Pada prinisipnya cara kerja algoritma tersebut adalah sebagai berikut :

  1. Bandingkan x dengan nilai tengah yang didapat dari kelompok array.
  2. Jika x sama dengan nilai tengah, kita kembalikan index dari x
  3. Jika x lebih besar dari nilai tengah, Maka nilai x pasti berada pada bagian kanan dari array, maka kita akan memfokuskan pencarian pada subarray sebelah kanan dari nilai tengah.
  4. Jika x lebih kecil dari nilai tengah, Maka nilai x berada pada sebelah kiri dari array. maka kita akan memfokuskan pencarian pada subarray sebelah kiri dari nilai tengah.

Binary-Search
image

Gambar diatas kita memiliki kelompok data yang terdiri dari 10 record. Dengan low index 0 dan high index 9. Kemudian kita ingin mencari x = 23

  1. Cari index yang berada di tengah, ada di M=4
  2. Nilai dari nilai tengah (M) =4 adalah 16, kemudian bandingkan dengan angka 23. Jika lebih besar x maka, kita akan melakukan pencarian ke kanan. Ganti Low Index dengan M + 1 dan High Index masih di angka 9.
  3. Antara index 5 dan index 9 didapat index tengah (M) = 7, kemudian didapat nilai dari M adalah 56. Bandingkan dengan angka x , sekarang nilai x lebih kecil daripada nilai tengah. Pencarian akan dilakukan ke kiri, diantara index ke 5 dan index M-1 yaitu index ke 6
  4. Nilai tengah antara index ke 5 dan ke 6, maka didapat index ke 5 dengan nilai 23. Maka nilai dari x sudah ditemukan.

Bagaimana implementasi pada golang, mari kita lihat buat code dibawah ini :


//Binary ...
func Binary(arrayParams []int, start int, totalRecord int, searchVariable int) int {
	totalRecord = totalRecord - 1
	for start <= totalRecord {
		mid := start + (totalRecord-start)/2
		if arrayParams[mid] == searchVariable {
			return mid
		}
		if arrayParams[mid] < searchVariable {
			start = mid + 1
		} else {
			totalRecord = mid - 1
		}
	}
	return -1
}

Kemudian impementasi pada main.go

package main

import (
	"fmt"
	"search"
	"strconv"
)

func main() {
	arr := []int{2, 5, 8, 12, 16, 23, 28, 56, 72, 92}
	x := 23
	i := search.Binary(arr, 0, len(arr), x)
	if i < 0 {
		fmt.Println(`not found`)
	} else {
		fmt.Println(`value found, index = ` + strconv.Itoa(i))
	}
}

 

Kemudian ketika kita jalankan code diatas, maka hasilnya akan seperti ini :

Screen Shot 2019-03-09 at 19.16.45

Dump large mysql database

https://pub.monospacelabs.com/developer-story-implementing-a-migrator-for-a-legacy-crm-d97deb22955a

an engineer has a way to backup their database, I have an experience how to backup large mysql database. The challenge is monitor the process when backup is already done. I’ve been search on google, the forum usually give the suggestion using pv, here the link . But i don’t know why pv not works on my server. progress bar always zero percent when dump has been started.

So this simple way, maybe shortcut to monitor process dump large database.

First we run mysqldump to starting the dump process.

mysqldump -u root -px xxxxxxxxxxxxxx — databases your_database — flush-logs — result-file=backup.sql — log-error=error.log

mysqldump is command for dump, and dont forget always add this option — log-error=error.log , because we want to know if something happen, we get the error.

So we just waiting, and try to check with

ps ax|grep mysql

it will show the process list mysql, If dump still running, you will see the command still exist there. If dump process success, the error.log doesn’t appear on directory. But if it exist, you have to check it, because dump process is failed.

I know this not best approach to doing this, because we still don’t know how long the backup will be done. But maybe this simple think you can try. If you have a experience how monitor this case, maybe you can give a comment in section below 😀 .

 

Go Language

Introduction

Go atau lebih dikenal dengan Golang adalah bahasa pemrograman yang dikembangkan oleh Google pada tahun 2007, project ini diprakrasai oleh Robert Griesemer, Rob Pike dan Ken Thompson. Golang sendiri memiliki kemiripan syntax dengan C, dan sudah menyediakan garbage collection, type safety , dynamic-typing dan banyak sekali library-library yang sudah disediakan. Fokus dari goalng sendiri adalah untuk membuat apps yang scalable, simple dan sangat mudah.

Kenapa Harus Golang?

Kenapa harus memilih golang sebagai bahasa untuk aplikasi server? Sementara banyak bahasa bahasa lain yang lebih dahulu dan lebih familiar seperti python, ruby dan nodejs yang bisa melakukan hal serupa.

Ini kelebihan yang bisa didapatkan jika memilih Go sebagai bahasa pemrograman

  • Concurency adalah bagian yang tidak terpisahkan dari sebuah bahasa pemrograman. Golang menyediakan fitur Goroutines dan channels yang bisa digunakan untuk membuat aplikasi yang multithread (hal ini akan dijelaskan lebih detail nanti).
  • Golang adalah compiled language. Semua souce akan dicomple menjadi native binary, hal ini yang tidak ada di beberapa bahasa interpreted seperti Javascript yang digunakan pada nodejs.
  • Sangat mudah digunakan dengan dukungan dokumentasi yang lengkap. Dukungan komunitas golang yang sudah banyak, membuat para programmer tidak kesulitan untuk mencari dokumentasi.
  • Compiler dari go support static linking. Semua code yang telah di compile akan menjadi sebuah binary yang bisa di deploy ke server tanpa perlu khawatir akan dependency.

Installation

Golang bisa digunakan di tiga platform, yaitu Mac, Windows dan Linux.

Mac

Download installer OS X dari https://golang.org/dl/. klik dua kali untuk memulai installasi. Ikuti petunjuknya dan golang akan terinstall di /usr/ local/ go kemudian tambahkan folder /usr/local/go/bin ke environtment variable PATH anda.

Windows

Download installer MSI dari https://golang.org/dl/. klik dua kali untuk memulai installasi. Ikuti petunjuknya dan golang akan terinstall di c:\Go kemudian tambahkan folder c:\Go\bin ke environtment variable PATH anda.

Linux

Download tar file dari https://golang.org/dl/ dan unzip ke dalam folder /usr/local. kemudian tambahkan folder /usr/local/go/bin ke environtment variable PATH anda.

GOPATH dan Workspace

Sebelum kita bisa untuk menggunakan golang, ada hal yang perlu kita setting. Kita perlu menyiapkan workspace untuk project yang akan kita buat. Gopath merupakan environtment variable yang digunakan untuk menunjukan lokasi yang berisi project-project Go, beserta file binary mereka.

Di dalam folder Gopath, setidaknya ada 3 buah subfolder yaitu src, bin dan pkg. Semua project yang anda buat akan ditempatkan pada folder $GOPATH/src. Misal kita akan membuat project ngoprek, maka folder tersebut haruslah berada di $GOPATH/src/ngoprek.

Struktur Program dan Hello World

Sebelum kita membahas lebih jauh golang programming, mari kita pelajari dahulu struktur minimum dari sebuah program golang. Biasanya di dalam sebuah program golang ada beberapa bagian di bawah ini :

  • Package Declaration
  • Import Packages
  • Function
  • Variables
  • Statements and Expressions
  • Comments

Mari kita buat sebuah program sederhana yang mencetak kata sakti yaitu “Hello World”

package main

import "fmt"

func main() {
   /* Cetak Hello World */
   fmt.Println("Hello, World!")
}

Mari kita bahas tiap line dari code diatas

  • Baris pertama dari program ini yaitu package main yang menunjukan nama package. Main package merupakan starting point untuk menjalankan program. Setiap file go, wajib memiliki nama package berdasarkan nama path yang terkait dengan file go tersebut
  • Baris berikutnya yang berisi import “fmt” , ini ialah perintah kepada Go compiler untuk menggunakan package fmt. Sehingga kita bisa menggunakan method-method yang ada di dalam package tersebut.
  • Baris berikutnya ialah func main() { , fungsi main ini memberi tahu dimana eksekusi program harus dimulai. Seperti di java, semua harus dari fungsi main.
  • fmt.Println() Merupakan method di fmt yang bertugas untuk mencetak string Hellow World. Perlu dicatat bahwa method ini menggunakan huruf capital, karena di Go method yang menggunakan huruf capital merupakan public method.

Setelah menuliskan program diatas, save file dengan nama hello.go, kita bisa mengkesekusi code dengan membuka command promt dan ketik go run hello.go

Rsync Without Password

1. Test rsync over ssh (with password):

Do a rsync to make sure it asks for the password for your account on the remote server, and successfully copies the files to the remote server.

The following example will synchronize the local folder /home/test to the remote folder /backup/test (on 192.168.200.10 server).

This should ask you for the password of your account on the remote server.

rsync -avz -e ssh /home/test/ user@192.168.200.10:/backup/test/
2. ssh-keygen generates keys.

Now setup ssh so that it doesn’t ask for password when you perform ssh. Use ssh-keygen on local server to generate public and private keys.

$ ssh-keygen
Enter passphrase (empty for no passphrase):

Enter same passphrase again: Note: When it asks you to enter the passphrase just press enter key, and do not give any password here.

3. ssh-copy-id copies public key to remote host

Use ssh-copy-id, to copy the public key to the remote host.

ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.200.10
Note: The above will ask the password for your account on the remote host, and copy the public key automatically to the appropriate location. If ssh-copy-id doesn’t work for you, use the method we discussed earlier to setup ssh password less login.

4. Perform rsync over ssh without password

Now, you should be able to ssh to remote host without entering the password.

ssh 192.168.200.10
Perform the rsync again, it should not ask you to enter any password this time.

rsync -avz -e ssh /home/test/ user@192.168.200.10:/backup/test/

Setting IP Ubuntu

Untuk mengetahui network interface yang ada di ubuntu, tinggal jalankan

ip link show

Dan akan muncul list network interface, kemudian setup IP dengan mengetikan command dibawah ini

sudo vi /etc/network/interfaces

Kemudian setting IP yang diinginkan, sample seperti ini :

auto lo
iface lo inet loopback

auto ens18
iface ens18 inet static
        address xxx.xxx.xxx.xxx
        netmask xxx.xxx.xxx.xxx
        gateway xxx.xxx.xxx.xxx
        dns-nameservers xxx.xxx.xxx.xxx 8.8.8.8

setelah itu jalankan command berikut

sudo ifup ens18

Share localhost menggunakan ngork

Dalam development, terkadang kita ingin agar local dev kita bisa diakses oleh mesin lain melalui internet. Dengan menggunakan ngork kita bisa membuat secure tunnel yang bisa diakses melalui URL yang sudah di sediakan oleh ngrok.

Kita bisa mendownload ngork disini , bisa didownload disesuaikan dengan OS yang digunakan. Cara menggunakan ngrok cukup mudah, setelah mendownload ngork kita bisa menggunakan dengan command dibawah ini :

./ngrok http 80

Setelah command tersebut dijalankan, ngrok akan memberikan alamat URL forwarding ke port 80 dari mesin kita. Seperti dibawah ini

Forwading http://23357e7f.ngork.io

Forwading https://23357e7f.ngork.io

Coba akses via browser url dibawah http://23357e7f.ngork.io & https://23357e7f.ngork.io , sites local anda sudah live dan bisa digunakan untuk share dengan tim development anda. ngork akan selalu men-generate unique url setiap kali anda merestart ngork.

Untuk explore fitur yang lain dari ngork, bisa menggunakan command dibawah ini :

./ngrok help

Selamat mencoba 😀

SSL Dengan LetsEncrypt

letsencrypt

Sebenarnya ini bukan hal yang sering saya lakukan, mungkin kadang-kadang 2 bulan bisa sekali ada tugas untuk setup TLS/SSL sertifikat. Karena mungkin faktor pelupa yang sangat akut, saya akan mendokumentasikan beberapa shortcut yang sering saya gunakan.

Jika kita mempunyai domain yang belum menggunakan HTTPS, tidak ada alasan lagi bagi kalian untuk tidak menggunakannya, karena sertifikat TLS/SSL sudah bisa didapatkan gratis di LetsEncrypt. Di tulisan kali ini saya akan coba memasang LetsEncrypt di server yang sudah terinstall nginx.

Instal Certbot

sudo add-apt-repository ppa:certbot/certbot

sudo apt-get update

sudo apt-get install python-certbot-nginx

Setup Nginx

sudo vi /etc/nginx/sites-available/default

cari line yang berisi server_name dan ubah sesuai domain yang sudah kamu miliki, sebagai contoh kabayan.com. Maka ubah menjadi seperti ini :

server_name kabayan.com;

Untuk melihat apakah configurasi nginx nya sudah benar, bisa mengunakan command sebagai berikut :

nginx -t

Jika tidak ada error, silahkan reload service nginx dengan command sebagai berikut :

sudo service nginx restart

Memasang Sertifikat

Certbot memiliki berbagai cara untuk mendapatkan sertifikat, salah satu plugin yang bisa digunakan adalah dengan mengunakan plugin nginx. Plugin inilah yang akan Continue reading “SSL Dengan LetsEncrypt”

Legok tapak genteng kadek

“Lamun hirup hoyong enjoy, kudu bisa praktekeun legok tapak genteng kadek ” , kata bapak warkop di obrolan tengah malam. Dengan ditemenin kopi si bapak cerita soal guyon dan falsafah hidup. Intinya mau dihujat, dicibir segimana pun, jangan pernah mempengaruhi kebahagiaan kita.

Siapa bapak warkop itu?

ada sebuah foto dipojok warkop dengan latar belakang pesawat N250 dan sejumlah karyawan PT Dirgantara Indonesia. Usut punya usut ternyata si bapak adalah mantan anak buah Pak B.J Habibie waktu beliau kerja di PT DI, membangun industri pesawat Indonesia. Ketika PT DI collaps, bapak tersebut kehilangan pekerjaannya. Tawaran dari luar negeri berdatangan mungkin dengan gaji yang menggiurkan.

Tapi karena idealisme dan kecintaan nya terhadap Indonesia, daripada membuat negara orang maju. Beliau lebih memilih berwirausaha membuka warung kopi di depan kampung Babakan Fakultas Bogor. Suka duka pasti dialami bapak itu, gua cuma tidak bisa membayangkan cercaan yang diterima si bapak yang datang dari keluarga besarnya, memilih meninggalkan kemewahan untuk mempertahankan idealismenya.

Si bapak jalan terus, dengan falsafah Legok tapak genteng kadek ( Banyak pengetahuannya atau pengalamannya), Bahwa hidup itu memang terdiri dari berbagai macam pengalaman yang harus dihadapin, jadi menurut si bapak kita harus bisa kuat mental dalam menghadapi hidup.

Baru kali ini gua dibuatkan kopi, oleh seorang teknisi jenius yang pernah membuat sejarah di Indonesia.

genteng