Enkripsi tingkat kolom database pada microservice data kepegawaian
- Peran
- Back End Developer Intern
- Periode
- Jul 2024 – Feb 2025 · proyek skripsi
- Perusahaan
- PT Indonesia Indicator
- Stack
- Spring Boot · PostgreSQL · pgcrypto · GnuPG
Masalah
UU No. 27 Tahun 2022 tentang Pelindungan Data Pribadi mewajibkan data seperti NIK, NPWP, No. KK, dan alamat pegawai dilindungi dari akses tidak sah. Di arsitektur microservices data itu dilayani banyak komponen, jadi butuh enkripsi yang kuat tapi tetap ringan.
Pendekatan
Enkripsi tingkat kolom di PostgreSQL: trigger PL/pgSQL mengenkripsi 4 kolom sensitif sebelum INSERT/UPDATE dengan pgcrypto dan kunci PGP dari GnuPG, lalu fungsi dekripsi dipanggil lewat LATERAL saat data dibaca. Blowfish dan AES-256 diuji dalam mode simetris dan asimetris untuk 0–500 data.
Hasil
Pada mode simetris, Blowfish ±45% lebih cepat dari AES-256 untuk 500 data (INSERT ±3,0 vs ±5,4 detik; GET ±2,2 vs ±4,0 detik). Dekripsi asimetris jauh lebih lambat (±18 menit untuk 500 data). Rekomendasi: Blowfish bila prioritas kecepatan, AES-256 bila prioritas keamanan.
Konteks
Sistem kepegawaian PT Indonesia Indicator berjalan di arsitektur microservices: permintaan dari client masuk lewat API Gateway lalu diteruskan ke layanan seperti ERM, HRIS, Attendance, dan Ticketing. Layanan HRIS memakai PostgreSQL sebagai basis data utama, dan menyimpan data pegawai yang termasuk data pribadi menurut UU No. 27 Tahun 2022: NIK, NPWP, No. KK, dan alamat.
Tujuannya: data sensitif tetap terlindungi meskipun database atau backup-nya bocor, tanpa membuat layanan menjadi lambat.
Arsitektur
Client → API Gateway → Service HRIS (Spring Boot) → PostgreSQL + pgcrypto
Enkripsi dan dekripsi dilakukan di tingkat database, sehingga layanan lain tidak perlu menyimpan logika kriptografi sendiri.
Implementasi
Trigger BEFORE INSERT OR UPDATE pada tabel employee memanggil fungsi yang mengenkripsi empat kolom sensitif dengan kunci publik:
CREATE OR REPLACE FUNCTION encrypt_data_table_employee()
RETURNS TRIGGER AS $$
DECLARE
pub_key BYTEA := dearmor(pg_read_file('keys/pub.key'));
options TEXT := 'cipher-algo=bf, unicode-mode=1';
BEGIN
NEW.nik := pgp_pub_encrypt(NEW.nik::TEXT, pub_key, options);
NEW.npwp := pgp_pub_encrypt(NEW.npwp::TEXT, pub_key, options);
NEW.alamat := pgp_pub_encrypt(NEW.alamat::TEXT, pub_key, options);
NEW.no_kk := pgp_pub_encrypt(NEW.no_kk::TEXT, pub_key, options);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
Saat dibaca, fungsi decrypt_employee_data (memakai pgp_pub_decrypt dan kunci privat) dipanggil per baris lewat LATERAL, sehingga REST API langsung menerima data yang sudah didekripsi:
SELECT e.id, e.name, d.decrypted_nik, d.decrypted_npwp
FROM employee e,
LATERAL decrypt_employee_data(e.nik, e.npwp, e.alamat, e.no_kk) AS d;
Pengujian
Waktu respons diukur dari Spring Boot dengan MockMvc: POST /api/employee untuk menyimpan data (enkripsi) dan GET /api/employees/all untuk mengambil semuanya (dekripsi), dengan jumlah data 0 sampai 500, untuk mode simetris (pgp_sym_*) dan asimetris (pgp_pub_*).
| Mode | Operasi (500 data) | AES-256 | Blowfish |
|---|---|---|---|
| Simetris | INSERT | ±5,4 detik | ±3,0 detik |
| Simetris | GET | ±4,0 detik | ±2,2 detik |
| Asimetris | GET | ±18 menit | ±18 menit |
Angka dibaca dari grafik hasil pengujian di skripsi dan dibulatkan.
Dekripsi dengan kunci publik/privat menjadi titik paling mahal: mengambil 500 data butuh belasan menit, sementara mode simetris hanya beberapa detik.
Perbandingan algoritma
| Algoritma | Jenis | Karakteristik | Dipakai untuk |
|---|---|---|---|
| AES-256 | Simetris, blok 128-bit, 14 putaran | Ketahanan kriptografi lebih kuat, tetapi lebih lambat di pengujian ini. | Pilihan bila prioritas utama keamanan. |
| Blowfish | Simetris, blok 64-bit, kunci hingga 448-bit | Paling cepat di pengujian dan skalanya lebih baik saat data bertambah. | Pilihan bila prioritas utama kecepatan. |
| RSA | Asimetris (kunci publik/privat) | Memisahkan kunci untuk enkripsi dan dekripsi, tetapi dekripsinya sangat lambat. | Pasangan kunci PGP (GnuPG) untuk pgp_pub_encrypt / pgp_pub_decrypt. |
Manajemen kunci
Pasangan kunci PGP dibuat dengan GnuPG. Kunci publik dipakai trigger enkripsi, sedangkan kunci privat beserta passphrase-nya hanya dipakai fungsi dekripsi. Kedua kunci dibaca dari direktori server database dengan pg_read_file, sehingga tidak pernah dikirim lewat API.
Hasil & pelajaran
- Enkripsi tingkat kolom berhasil menjaga kerahasiaan data sensitif tanpa mengubah layanan lain di arsitektur microservices.
- Blowfish unggul dari sisi kecepatan; AES-256 tetap direkomendasikan bila prioritasnya ketahanan terhadap serangan kriptografi modern.
- Langkah berikutnya: pengujian dengan volume data yang jauh lebih besar, rotasi kunci berkala, dan pemantauan kinerja serta keamanan secara rutin.