Enkripsi Data

Dokumentasi lengkap seluruh field database yang dienkripsi pada setiap modul OnePlatform, beserta penjelasan teknis implementasi dan batasan pencarian data terenkripsi.

Cara Kerja
OnePlatform menggunakan fitur encrypted cast bawaan Laravel. Setiap field yang ditandai dengan cast ini akan secara otomatis dienkripsi menggunakan AES-256-CBC saat disimpan ke database, dan didekripsi saat dibaca oleh aplikasi. Data di database tersimpan sebagai ciphertext yang tidak dapat dibaca tanpa APP_KEY.

Modul Accounting -- BankAccount

Model BankAccount menyimpan informasi rekening bank perusahaan. Hampir seluruh field sensitifnya dienkripsi karena mengandung data identitas keuangan kritis.

Field Tipe Cast Kategori Data Deskripsi
account_number encrypted Identitas Bank Nomor rekening bank perusahaan (contoh: 1234567890)
swift_code encrypted Identitas Bank Kode SWIFT/BIC untuk transfer internasional (contoh: CENAIDJA)
iban encrypted Identitas Bank International Bank Account Number untuk transaksi lintas negara
routing_number encrypted Identitas Bank Nomor routing bank (ABA routing number) untuk transfer domestik
api_config encrypted:array Konfigurasi Rahasia Konfigurasi API perbankan termasuk client ID, secret key, dan endpoint. Disimpan sebagai array terenkripsi.
online_banking encrypted:array Konfigurasi Rahasia Kredensial dan pengaturan online banking termasuk username dan token akses. Disimpan sebagai array terenkripsi.

Modul Finance -- Vendor & Customer

Model Vendor dan Customer menyimpan data mitra bisnis termasuk informasi pajak dan perbankan yang bersifat rahasia.

Vendor

Field Tipe Cast Kategori Data Deskripsi
tax_number encrypted Identitas Pajak Nomor Pokok Wajib Pajak (NPWP) vendor
bank_details encrypted Identitas Bank Detail rekening bank vendor untuk pembayaran (nama bank, nomor rekening, nama pemilik)

Customer

Field Tipe Cast Kategori Data Deskripsi
tax_number encrypted Identitas Pajak Nomor Pokok Wajib Pajak (NPWP) customer
bank_details encrypted Identitas Bank Detail rekening bank customer untuk penerimaan (nama bank, nomor rekening, nama pemilik)

Modul Finance -- CreditCard

Model CreditCard menyimpan data kartu kredit perusahaan. Seluruh informasi kartu dienkripsi sesuai standar keamanan PCI-DSS.

Field Tipe Cast Kategori Data Deskripsi
card_number_encrypted encrypted Data Keuangan Nomor kartu kredit lengkap (16 digit). Hanya 4 digit terakhir yang ditampilkan di UI.
cardholder_name encrypted Data Pribadi (PII) Nama pemegang kartu kredit sesuai yang tercetak di kartu
expiry_date encrypted Data Keuangan Tanggal kedaluwarsa kartu kredit (format: MM/YY)
Kepatuhan PCI-DSS
Penyimpanan nomor kartu kredit harus mematuhi standar PCI-DSS. Enkripsi AES-256-CBC memenuhi persyaratan enkripsi PCI-DSS, namun pastikan juga CVV/CVC tidak pernah disimpan di database sesuai regulasi.

Modul Purchasing -- PurchasePayment

Model PurchasePayment menyimpan data pembayaran pembelian yang mencakup informasi rekening dan referensi transaksi.

Field Tipe Cast Kategori Data Deskripsi
bank_account encrypted Identitas Bank Nomor rekening bank tujuan pembayaran ke vendor
reference_number encrypted Data Keuangan Nomor referensi transaksi pembayaran dari bank (bukti transfer)

Modul Point of Sales -- Member

Model Member (POS) menyimpan data pribadi anggota/pelanggan yang merupakan Personally Identifiable Information (PII) dan dilindungi undang-undang privasi.

Field Tipe Cast Kategori Data Deskripsi
phone encrypted Data Pribadi (PII) Nomor telepon/HP anggota POS
email encrypted Data Pribadi (PII) Alamat email anggota POS
birth_date encrypted Data Pribadi (PII) Tanggal lahir anggota POS
address encrypted Data Pribadi (PII) Alamat lengkap tempat tinggal anggota POS
Perlindungan Data Pribadi
Enkripsi data pribadi anggota POS sejalan dengan Undang-Undang Perlindungan Data Pribadi (UU PDP) No. 27 Tahun 2022 yang mewajibkan pengendali data untuk melindungi data pribadi menggunakan langkah teknis yang memadai.

Modul Koperasi -- Member & Saving

Modul Koperasi menyimpan data keuangan anggota koperasi yang bersifat sangat rahasia, termasuk simpanan pokok, simpanan wajib, dan saldo tabungan.

Koperasi Member

Field Tipe Cast Kategori Data Deskripsi
simpanan_pokok encrypted Data Keuangan Simpanan pokok anggota koperasi yang dibayarkan satu kali saat pendaftaran
simpanan_wajib encrypted Data Keuangan Simpanan wajib anggota koperasi yang dibayarkan secara rutin setiap bulan

Koperasi Saving

Field Tipe Cast Kategori Data Deskripsi
balance encrypted Data Keuangan Saldo tabungan sukarela anggota koperasi saat ini

Ringkasan Seluruh Field Terenkripsi

Tabel berikut merangkum seluruh field yang dienkripsi di OnePlatform dalam satu pandangan:

Modul Model Jumlah Field Field Terenkripsi
Accounting BankAccount 6 account_number, swift_code, iban, routing_number, api_config, online_banking
Finance Vendor 2 tax_number, bank_details
Finance Customer 2 tax_number, bank_details
Finance CreditCard 3 card_number_encrypted, cardholder_name, expiry_date
Purchasing PurchasePayment 2 bank_account, reference_number
POS Member 4 phone, email, birth_date, address
Koperasi Member 2 simpanan_pokok, simpanan_wajib
Koperasi Saving 1 balance
Total
Terdapat 22 field yang dienkripsi di 8 model dari 5 modul yang berbeda. Semua menggunakan algoritma AES-256-CBC melalui Laravel encrypted cast.

Implementasi Teknis: Laravel Encrypted Cast

Berikut penjelasan teknis tentang bagaimana enkripsi diimplementasikan pada model Eloquent di OnePlatform.

Model Eloquent -- Contoh Definisi Cast
// Contoh: app/Modules/Accounting/Models/BankAccount.php

protected function casts(): array
{
    return [
        'account_number'  => 'encrypted',
        'swift_code'      => 'encrypted',
        'iban'            => 'encrypted',
        'routing_number'  => 'encrypted',
        'api_config'      => 'encrypted:array',
        'online_banking'  => 'encrypted:array',
    ];
}

Proses Enkripsi (Saat Menyimpan)

Laravel mengambil APP_KEY dari konfigurasi, men-generate Initialization Vector (IV) acak, lalu mengenkripsi data menggunakan AES-256-CBC. Hasil enkripsi (ciphertext + IV + MAC) di-encode ke Base64 dan disimpan sebagai string di kolom database bertipe TEXT atau LONGTEXT.

Proses Dekripsi (Saat Membaca)

Saat model di-load dari database, Laravel secara otomatis men-decode Base64, memverifikasi MAC (Message Authentication Code) untuk memastikan integritas data, lalu mendekripsi ciphertext menggunakan APP_KEY dan IV yang tersimpan. Data dikembalikan dalam bentuk plaintext ke aplikasi.

Tipe encrypted:array

Untuk field seperti api_config dan online_banking, digunakan cast encrypted:array. Data array PHP di-serialize ke JSON terlebih dahulu, lalu dienkripsi. Saat dibaca, data didekripsi lalu di-deserialize kembali menjadi array PHP.

Batasan Pencarian Data Terenkripsi

Enkripsi memberikan keamanan yang kuat, namun ada trade-off penting yang perlu dipahami terkait kemampuan pencarian:

Yang Dapat Dilakukan

  • ✓ Membaca dan menampilkan data terenkripsi secara normal
  • ✓ Menyimpan dan mengubah data terenkripsi
  • ✓ Memfilter data setelah di-load ke memori (PHP-level)
  • ✓ Mengurutkan data setelah di-load ke collection
  • ✓ Pencarian berdasarkan field yang tidak terenkripsi (ID, nama, dll)
  • ✓ Export data yang sudah didekripsi ke laporan

Yang Tidak Dapat Dilakukan

  • ✗ Query WHERE langsung pada field terenkripsi di SQL
  • ✗ LIKE search / pencarian parsial di database
  • ✗ ORDER BY pada kolom terenkripsi di level database
  • ✗ Index database pada kolom terenkripsi
  • ✗ Aggregate functions (SUM, AVG) langsung di SQL
  • ✗ JOIN berdasarkan nilai field terenkripsi
Strategi Pencarian
Karena data terenkripsi tidak dapat di-query langsung di SQL, OnePlatform menggunakan strategi berikut: (1) Pencarian dilakukan berdasarkan field yang tidak terenkripsi seperti ID, nama, atau kode. (2) Untuk field terenkripsi, data di-load terlebih dahulu lalu difilter menggunakan Laravel Collection di level PHP. (3) Untuk kebutuhan pencarian yang sering, pertimbangkan menyimpan hash blind index terpisah.

Tampilan Data di Database

Berikut perbandingan bagaimana data terlihat di aplikasi versus di database:

Perbandingan: Aplikasi vs Database
// Di Aplikasi (setelah dekripsi):
"account_number" => "1234567890"
"swift_code"     => "CENAIDJA"
"tax_number"     => "01.234.567.8-901.000"

// Di Database (ciphertext terenkripsi):
"account_number" => "eyJpdiI6IkpUZ3JKQk..."
"swift_code"     => "eyJpdiI6InVGS0RaWk..."
"tax_number"     => "eyJpdiI6Im1CY2tPWX..."
Peringatan Keamanan
Jika seseorang mendapatkan akses langsung ke database (misalnya melalui SQL injection atau backup yang dicuri), mereka hanya akan melihat ciphertext yang tidak dapat dibaca. Data hanya dapat didekripsi dengan APP_KEY yang tersimpan di file .env server aplikasi.