Enkripsi Value Sensitive di Database Dengan SpringBoot dan AspectJ

Table dengan beberapa field yang ter-enkripsi

Intro

Terkadang kita perlu enkripsi beberapa bagian penting dari data kita di database, seperti nama lengkap, nomer telepon dan nomer ktp, untuk mencegah kebocoran data di database kita yang akhirnya akan merugikan banyak pihak (data breach atau data leak).

Ada banyak cara untuk melakukan enkripsi field di table database, namun cara paling mudah adalah dengan melakukan enkripsi di level aplikasi. Pada contoh dibawah ini, saya menggunakan aplikasi sederhana diatas Spring Boot dan JPA, serta library Jasypt untuk melakukan enkripsi sederhana menggunakan class PBEStringEncryptor .

Basic Code

Seperti biasa, kita mulai dengan pom.xml.

Dan main method,

Satu file controller biasa untuk menghasilkan API,

Satu java class sebagai mapping dari database,

Dan satu repository interface biasa,

Semua code diatas berguna untuk membuat suatu aplikasi sederhana yang memiliki fungsi menyediakanAPI dan query ke database.

A Much More Complicated Code

Sekarang kita akan membuat code untuk melakukan enkripsi dan dekripsi value di table database.

Untuk memudahkan, dan supaya terlihat kekinian , saya menggunakan annotation untuk menandai bagian mana dari API kita yang akan di-encrypt dan decrypt.

Serta file java yang menggunakan AspectJ untuk melakukan enkripsi dan dekripsi secara on the fly terhadap data yang akan di-insert, dan di-select dari database.

Sekarang aplikasi akan melakukan enkripsi terhadap semua parameter di method yang memiliki annotation enrypt dan dekripsi terhadap semua method ber-annotation decrypt.

How to Test

Kita bisa menggunakan curl sederhana untuk meng-insert data ke database,

curl -L -X POST 'http://localhost:8080/save' \
-H 'Content-Type: application/json' \
--data-raw '{
"fullname":"Edwin",
"address":"Jakarta",
"phonenumber":"08161445622"
}'

Output dari API tersebut, apabila sukses, adalah sebagai berikut

{"id":17}

Kita bisa cek apa isi data dengan id 17 menggunakan curl berikut,

curl -L -X GET 'http://localhost:8080/17'

Dan hasilnya adalah,

{
"id": 17,
"fullname": "Edwin",
"address": "Jakarta",
"phonenumber": "08161445622",
"createdDate": "2020-05-04T15:49:24.000+0000"
}

Padahal apabila kita query ke database menggunakan id yang sama,

select * from t_user_profile
where id = 17;
id,fullname,address,phonenumber,created_date
17,Vc+T5/JRJYPDcvJ5xuxEwQ==,ai6Zj4cT+B+o1DjJdSzH7A==,BtNMJLTjScVUlG7VQ/vXJMri0QhnEel+,2020-05-04 22:49:24

Dan seperti yang sudah terlihat, data yang ter-eknripsi di database bisa di-translate oleh API aplikasi kita sehingga terlihat seolah-olah tanpa enkripsi sama sekali.

Gunakan curl berikut untuk menampilkan semua data yang ada di table t_user_profile.

curl -L -X GET 'http://localhost:8080/'

nb.

Enkripsi dan Dekripsi dijalankan secara paralel menggunakan classPooled Encryptor milik Jasypt untuk memanfaatkan setiap processor yang tersedia di cpu dan berguna untuk mengurangi waktu yang dibutuhkan untuk enkripsi-dekripsi data. Dan di laptop saya setiap curl membutuhkan waktu kurang dari 10milisecond.

Code lengkapnya bisa di-download dari Github,

https://github.com/edwin/spring-boot-jpa-aspectj-encryption

--

--

Muhammad Edwin
Development using RedHat Product. (This is an Unofficial Blog)

A RedHatter and Digital Nomad, with Jeans, Sneakers, Laptop and Coffees, anytime — anywhere.