Enkripsi Value Sensitive di Database Dengan SpringBoot dan AspectJ
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