Enkripsi MySQL dan Manajemen kunci

10

Saya sedang mengembangkan sistem intranet lokal dalam PHP / MySQL untuk mengelola data klien kami. Tampaknya praktik terbaik adalah mengenkripsi data sensitif pada server MySQL ketika sedang dimasukkan.

Saya tidak jelas, bagaimanapun, tentang apa yang akan menjadi cara terbaik untuk melakukan ini sementara masih memiliki data yang mudah diakses.

Sepertinya pertanyaan sulit untuk dijawab: di mana kunci disimpan? Bagaimana cara terbaik melindungi kunci? Jika kunci disimpan di mesin masing-masing pengguna, bagaimana cara melindunginya jika mesin dieksploitasi? Jika kunci dieksploitasi, bagaimana cara mengubah kunci?

Jika kuncinya akan disimpan dalam DB, bagaimana cara melindunginya di sana? Bagaimana pengguna mengaksesnya?

stormdrain
sumber
Jenis enkripsi dan penyimpanan kunci akan tergantung pada jenis skenario yang ingin Anda cegah. Jelas, jika penyerang Anda mendapatkan root atau pengguna aplikasi di server, ia dapat menggunakan rutinitas yang sama untuk mendekripsi seperti yang digunakan aplikasi Anda. Jadi, skenario apa yang ingin Anda cegah? Seseorang mencuri cadangan? Serangan injeksi SQL? Sesuatu yang lain
Aleksandar Ivanisevic
Terima kasih balasannya! Saya tidak begitu peduli dengan backup. Saya lebih khawatir tentang seseorang yang mengeksploitasi mesin pengguna dan kemudian mengakses situs dari sana baik melalui injeksi SQL, atau menguatkan kredensial aplikasi pengguna. Saya tidak terlalu khawatir dengan mesin itu sendiri; kredensial su sangat kuat (saya tidak yakin bahwa su 100% aman).
stormdrain

Jawaban:

9

Sebenarnya tidak ada fitur bawaan MySQL untuk menangani pengaturan kunci terenkripsi yang canggih. Anda harus mengimplementasikan sebagian besar logika enkripsi dalam kode PHP dan / atau sisi browser (javascript?) Anda sendiri.

Tetapi kekhawatiran yang Anda nyatakan agak aneh: Sepertinya satu-satunya kekhawatiran Anda yang sebenarnya adalah injeksi SQL atau brute force (menebak-nebak, saya berasumsi) serangan dari desktop klien / workstation laptop. Itu membuat saya curiga bahwa Anda sudah merencanakan tindakan keamanan lain yang tidak disebutkan, dan Anda telah menganalisis kemungkinan jalan kompromi.

  • Pertama, saya berasumsi Anda memiliki aturan firewall yang melindungi host MySQL / PHP terhadap segala jenis akses dari IP klien jarak jauh yang tidak disetujui. Jika saya benar, masuk akal bahwa Anda hanya khawatir tentang serangan dari workstation pengguna yang dikompromikan.

  • Juga, saya berasumsi Anda mengerti bahwa jika penyerang pada host klien jarak jauh dapat meningkat ke root / Admin privs, atau secara langsung membahayakan akun pengguna sebenarnya, maka data klien tidak memiliki perlindungan apa pun terlepas dari enkripsi atau perlindungan lainnya. (Penyerang dapat membaca kunci dari mana saja mereka disimpan pada disk, atau mengintai mereka ketika pengguna yang sebenarnya memasukkan mereka saat masuk, dan kunci mengarah ke data.)

Mulai dari dua asumsi tersebut, masuk akal bagi kami untuk menyimpulkan bahwa hanya dua ancaman yang relevan adalah A) menebak dengan kasar, dan B) upaya injeksi SQL:

  • Jika penyerang tidak mengetahui kunci pengguna sebenarnya, atau jika ia menginginkan akses lebih dari sekadar data pengguna sebenarnya, ia dapat mencoba kredibilitas masuk log kasar untuk pengguna asli atau akun lain. (Secara teori, Anda dapat mengunci setiap akun ke IP klien jarak jauh tertentu, yang juga akan membantu membagi risiko-risikonya.)
  • Jika penyerang memang mendapatkan kunci yang valid untuk pengguna sebenarnya, ia memiliki jalan melewati layar masuk (yang mungkin cukup sederhana untuk diamankan), ke perut lembut kode aplikasi yang berpotensi buggy. Injeksi SQL yang berhasil dari konteks pengguna nyata dapat memberinya akses ke data klien lain juga.

Sekarang, mari kita bicara tentang bagaimana enkripsi sisi server berlaku untuk situasi ini:

  • Enkripsi sisi server pasti membantu melawan ancaman injeksi SQL. Jika nilai baris dienkripsi dalam tabel DB, penyerang hanya bisa melihat ciphertext omong kosong dari data milik akun lain. Ancaman terkandung, terkotak.
  • Namun, memaksa dengan kasar menebak kata sandi, tidak benar-benar menjadi lebih sulit bagi penyerang yang menghadapi enkripsi sisi server. Terlepas dari apakah kunci pengguna disimpan di server atau dihasilkan di tempat dari kata sandi, satu-satunya hal yang penting adalah apakah Anda memiliki kata sandi yang tepat. Server memutuskan untuk membiarkan Anda menggunakan kunci tersimpan yang valid karena memeriksa apakah kata sandi Anda benar, atau menghitung kunci yang valid untuk Anda karena kata sandi Anda adalah input yang benar untuk menghasilkan kunci itu.

Enkripsi sisi klien, di sisi lain, sebenarnya membuat serangan kata sandi brute force tidak relevan. Anda tidak dapat dengan kasar memaksa kunci yang dibangun dengan benar. Enkripsi sisi klien pada dasarnya menjaga tingkat perlindungan yang sama terhadap injeksi SQL seperti halnya enkripsi sisi server. Klien dapat meneruskan kunci ke server saat masuk, menyimpan salinan di memori sampai sesi selesai, yang menempatkan beban CPU crypto di server. Atau, klien dapat menangani enkripsi / dekripsi dengan sendirinya, di browser. Ada dua pasang surut dari kedua teknik ini:

  • Melewati kuncinya ke server jauh lebih mudah untuk dikodekan dan dikelola, dan biasanya jauh lebih cepat karena kode kripto yang lebih optimal (dikompilasi C, mungkin).
  • Pendekatan sisi klien murni memberikan keamanan ekstra, karena bahkan jika penyerang mendapatkan root di server, ia masih tidak dapat membaca data yang dienkripsi, dan ia tidak akan pernah bisa membacanya. Satu-satunya vektor serangan yang mungkin adalah kompromi workstation klien jarak jauh.

Akhirnya, saya akan mencatat bahwa ada beberapa kerugian operasional besar untuk mengenkripsi data dalam database. Karena representasi data terenkripsi pada dasarnya adalah pola acak, fitur basis data dasar seperti pengindeksan, bergabung, dll tidak akan berfungsi. Klien mengambil beban logika yang sangat besar, dan mungkin kehilangan banyak manfaat yang biasanya dimiliki oleh fitur basis data.

Ryan B. Lynch
sumber
1
Wow! Jawaban luar biasa dan menyeluruh; Terima kasih banyak. Selama beberapa hari terakhir, saya telah mempertimbangkan beberapa opsi, dan telah memutuskan untuk mencoba dan mengimplementasikan solusi sisi klien seperti yang Anda sarankan. Idealnya, kunci akan disimpan pada thumb drive yang hanya akan dipasang ketika pengguna bekerja pada sistem (keamanan fisik sangat ketat) dan kunci disimpan dalam memori hanya selama sesi berlangsung. Gagasannya adalah bahwa kunci hanya akan dapat diakses oleh sistem selama jam kerja ketika saya di sana untuk memantau lalu lintas, dll.
stormdrain
2

Anda mungkin ingin melihat ezNcrypt , yang menggunakan ecryptfs, kontrol akses, dan manajemen kunci untuk memberikan keamanan dan kinerja tinggi untuk enkripsi Linux dari database MySQL dan proses lainnya. Tidak, saya tidak bekerja untuk mereka.

Dan
sumber
2

Anda bisa menggunakan Scytale. Ini adalah proxy kripto NoSQL untuk DBMS dan aplikasi web modern. Mendukung enkripsi multi-penerima dan grup. Dipenuhi dengan cryptosystem RSA / AES yang kuat. Ini juga 100% gratis dan open-source.

https://bitbucket.org/maximelabelle/scytale

Maxime Labelle
sumber