Katakanlah saya ingin beberapa bagian dari perangkat lunak saya dienkripsi. Sebagai contoh, kredensial untuk database, dll. Saya perlu menyimpan nilai-nilai itu di suatu tempat, tetapi melakukan hal itu dalam cleartext akan membuatnya mudah bagi penyerang untuk mendapatkan akses yang tidak sah.
Namun, jika saya mengenkripsi beberapa cleartext, lalu di mana saya menyimpan kunci? Apa pun yang dapat diakses oleh perangkat lunak, penyerang yang teguh akan memiliki akses, tidak peduli tingkat kebingungannya:
- Katakanlah kunci dilindungi oleh model keamanan sistem file; tapi bagaimana dengan pengguna super (jahat), atau platform yang tidak memberikan kesetiaan seperti itu?
- Atau kuncinya adalah hardcoded menjadi binari perangkat lunak, tetapi selalu bisa didekompilasi dan bagaimana dengan perangkat lunak open source atau kode yang ditafsirkan?
- Jika kunci dihasilkan, algoritma seperti itu perlu deterministik (mungkin) dan kemudian masalah yang sama berlaku untuk seed.
- dll.
Kriptografi hanya sekuat tautan terlemah dalam rantainya dan ini sepertinya cukup longgar! Menganggap itu adalah alat yang tepat untuk pekerjaan itu (humor saya), lalu bagaimana seseorang bisa mengamankan informasi seperti itu dengan kuat?
Mengenai alat yang tepat untuk pekerjaan itu: Mungkin, dalam - misalnya - kasus akses layanan (DB, server otentikasi, dll.), Anda akan membatasi akses pada tingkat ini dengan akun layanan, mungkin dengan beberapa tingkat layanan mengaudit, dll. dan memiliki kredensial di cleartext tidak begitu mengkhawatirkan.
Namun bagi saya, itu masih tampak tidak memadai: Saya tidak ingin ada yang mencari-cari di tempat yang seharusnya tidak ada!
sumber
Jawaban:
Pertama-tama, saya tidak akan menyebut diri saya sebagai ahli keamanan, tetapi saya berada dalam posisi harus menjawab pertanyaan ini. Apa yang saya temukan sedikit mengejutkan saya: Tidak ada sistem yang sepenuhnya aman . Yah, saya kira sistem yang sepenuhnya aman akan menjadi salah satu di mana semua server dimatikan :)
Seseorang yang bekerja dengan saya pada saat itu menggambarkan mendesain sistem yang aman dalam hal meningkatkan standar bagi para penyusup. Jadi, setiap lapisan pengamanan mengurangi peluang serangan.
Misalnya, bahkan jika Anda benar-benar dapat mengamankan kunci privat, sistemnya tidak sepenuhnya aman. Tetapi, dengan benar menggunakan algoritma keamanan dan memperbarui dengan tambalan memunculkan bilah. Tapi, ya, komputer super yang cukup kuat dan diberi waktu yang cukup dapat merusak enkripsi. Saya yakin semua ini dipahami, jadi saya akan kembali pertanyaannya.
Pertanyaannya jelas jadi saya pertama-tama akan mencoba membahas masing-masing poin Anda:
Ya, jika Anda menggunakan sesuatu seperti Windows Key Store atau kunci privat TLS yang dienkripsi, Anda dihadapkan pada pengguna yang memiliki kata sandi (atau akses) ke kunci privat. Tapi, saya pikir Anda akan setuju yang meningkatkan standar. Sistem file ACL (jika diterapkan dengan benar) memberikan tingkat perlindungan yang cukup baik. Dan Anda berada dalam posisi untuk secara pribadi memeriksa dan mengetahui pengguna super Anda.
Ya, saya telah melihat kunci hardcoded dalam biner. Sekali lagi, ini sedikit meningkatkan bar. Seseorang yang menyerang sistem ini (jika itu adalah Java) harus memahami bahwa Java menghasilkan kode byte (dll) dan harus memahami cara mendekompilasinya. Jika Anda menggunakan bahasa yang menulis langsung ke kode mesin, Anda dapat melihat bahwa ini meningkatkan bilah sedikit lebih tinggi. Ini bukan solusi keamanan yang ideal, tetapi dapat memberikan tingkat perlindungan tertentu.
Ya, pada dasarnya maka algoritma menjadi informasi kunci pribadi untuk membuat kunci pribadi. Jadi, sekarang perlu dilindungi.
Jadi, saya pikir Anda telah mengidentifikasi masalah inti dengan kebijakan keamanan apa pun, manajemen kunci . Memiliki kebijakan manajemen utama di tempat adalah pusat untuk menyediakan sistem yang aman. Dan, itu adalah topik yang cukup luas .
Jadi, pertanyaannya adalah, seberapa amankah sistem Anda (dan, karenanya, kunci privat) perlu? Seberapa tinggi, dalam sistem Anda, apakah bilah perlu dinaikkan?
Sekarang, jika Anda bersedia membayar, ada beberapa orang di luar sana yang menghasilkan solusi untuk ini. Kami akhirnya menggunakan HSM (Modul Keamanan Perangkat Keras) . Ini pada dasarnya adalah server anti-perusak yang berisi kunci dalam perangkat keras. Kunci ini kemudian dapat digunakan untuk membuat kunci lain yang digunakan untuk enkripsi. Idenya di sini adalah bahwa (jika dikonfigurasi dengan benar), kuncinya tidak pernah meninggalkan HSM. HSM harganya sangat mahal . Tetapi dalam beberapa bisnis (misalnya melindungi data kartu kredit), biaya pelanggaran jauh lebih tinggi. Jadi, ada keseimbangan.
Banyak HSM menggunakan kartu kunci dari pemeliharaan dan admin fitur. Kuorum kartu kunci (misalkan 5 dari 9) harus dimasukkan secara fisik ke server untuk mengubah kunci. Jadi, ini meningkatkan standar dengan membiarkan pelanggaran jika kuorum pengguna super berkolusi.
Mungkin ada solusi perangkat lunak di luar sana yang menyediakan fitur serupa dengan HSM tapi saya tidak tahu apa itu.
Saya tahu ini hanya beberapa cara untuk menjawab pertanyaan, tapi saya harap ini membantu.
sumber
Apa yang Anda inginkan tidak dapat dilakukan.
Anda pada dasarnya menginginkan perlindungan dari orang-orang yang menjadi jahat. Dalam model Anda, pada titik tertentu seseorang akan memiliki akses ke kunci. Bagaimana jika orang itu jahat? Bagaimana jika ANDA berbahaya? Lihat, masalah saat Anda menyatakan tidak dapat dipecahkan kecuali dengan tidak memiliki kunci sama sekali.
Jadi jangan bekerja dengan kredensial Database tetapi mekanisme otentikasi lainnya. Tetapi bagaimanapun juga, seseorang pada suatu titik membutuhkan akses ke data dan bahwa seseorang dapat jahat.
sumber
Ini adalah salah satu masalah yang tidak dapat dipecahkan pada tingkat yang sama seperti saat itu dibuat. Kita harus mengambil langkah mundur ke beberapa filosofi dasar, dan mengikuti kaskade dengan harapan resolusi.
Filosofi pertama adalah "jangan pernah mempercayai klien", dan terkait erat "jika Anda benar-benar ingin menyimpan rahasia, jangan beri tahu siapa pun!"
Contoh sederhana adalah kredensial basis data, seperti yang Anda sebutkan. Jelas Anda ingin klien Anda memiliki akses ke sana, tetapi tidak ada Internet Stranger acak, sehingga Anda memerlukan semacam sistem identitas / verifikasi / login. Tetapi premis inti dari menyembunyikan ini adalah masalah: jika pengguna itu sendiri harus memiliki rahasia, tetapi Anda tidak ingin mereka tahu apa rahasia itu, yang bisa Anda lakukan hanyalah menyembunyikannya atau membuatnya sulit bagi mereka untuk membuka " paket rahasia ". Tetapi mereka masih bisa mengetahuinya, jadi sebaiknya Anda memiliki rencana cadangan!
Solusi termudah adalah, "jangan lakukan itu." Gunakan kredensial akun pengguna sendiri untuk mengizinkan akses tingkat klien ke database untuk perangkat lunak, dan hanya itu. Jika klien menjadi jahat, skenario terburuk harusnya klien dapat mengacaukan data mereka sendiri. Itu dia. Database dan sistem Anda seharusnya, paling banyak, sekarang berisi entri sampah dari klien itu, semata-mata untuk klien itu, tanpa ada orang lain (termasuk Anda) yang menderita kekacauan itu.
Ada beberapa kasus penggunaan khusus di mana Anda hanya ingin perangkat lunak yang dikerahkan melakukan sesuatu tetapi tidak semua orang di dunia dapat terhubung dan melakukan hal yang sama, tetapi untuk itu Anda hanya menyembunyikan rahasia dan satu-satunya alasan bagus untuk melakukannya adalah hanya untuk mengurangi sakit kepala atau aktivitas sistem. Jika info tersembunyi Anda menjadi rahasia umum, sebaiknya tidak menjadi game-breaking, paling buruknya menyebalkan.
Jika Anda berada di salah satu kasus penggunaan yang sempit, itu hanya tentang kebingungan, yang semuanya tentang menjadi kreatif. Ini sangat mirip dengan Code Golf, sungguh - kecuali Anda yang membuat puzzle. Hanya itu yang sebenarnya - sebuah teka-teki. Dan orang-orang suka memecahkan teka-teki, jadi sekali lagi, lebih baik tidak apa-apa ketika seseorang menemukannya.
Tetapi untuk sebagian besar hal di dunia, yang terbaik adalah beroperasi tanpa khawatir harus menyimpan rahasia dari pengguna. Sebaliknya, praktik terbaik adalah membiarkan pengguna mengetahui rahasia, menjadikannya tanggung jawab mereka untuk membantu melindunginya (nama pengguna dan kata sandi mereka, misalnya), dan membatasi risiko kerugian dari apa yang terjadi jika rahasia itu keluar atau disalahgunakan.
Dalam konteks kriptografi / keamanan "manajemen kunci" yang sebenarnya, jawaban "tempat menyimpan kunci pribadi" adalah "di tempat lain!" Enkripsi adalah perlindungan point-to-point, dan enkripsi kunci publik-swasta dirancang untuk melindungi informasi dalam perjalanan melalui ruang dan waktu. Kunci pribadi secara inheren rentan, dan melindunginya sebenarnya bukan masalah tumpang tindih enkripsi - itu mengamankan terhadap akses sepenuhnya. Dan jika Sistem harus mengaksesnya, maka Sistem itu sendiri harus diamankan - dan Anda tidak dapat melakukannya pada mesin klien. Mereka selalu dapat menjalankan VM, membuang RAM, mengendus lalu lintas jaringan mereka, menginstal proxy atau NIC virtual, mendekompilasi executable ... tidak secara sukarela terlibat dalam pertempuran kehilangan itu.
Sekarang jika Anda perlu melakukan sesuatu seperti DRM, di mana kebutuhan Anda untuk menyimpan rahasia sebenarnya didasarkan pada pengendalian penggunaan perangkat lunak itu sendiri, itu situasi yang sama sekali berbeda .
TLDR: Jangan menyimpan rahasia DARI pengguna, menjaga rahasia DENGAN pengguna.
sumber
Salah satu sistem yang saya gunakan saat ini bekerja dengan cara ini.
Tentu saja layanan yang dilindungi berjalan di luar jangkauan saya. Itu bisa berjalan di mesin saya di bawah akun yang berbeda (dan mungkin dalam wadah), tapi saya memiliki hak pengguna super dan kemudian bisa mencoba untuk menghindari batasan.
Pada dasarnya jika Anda memiliki pengguna super jahat, semua taruhan dibatalkan. Dan Anda harus mengasumsikan kehadiran pengguna super jahat dalam model ancaman Anda.
Jadi, Anda perlu mengisolasi layanan yang dilindungi dari mesin yang dapat diakses klien. Memindahkan layanan yang dilindungi ke mesin yang hanya dapat diakses melalui jaringan. Masukkan klien Anda ke mesin virtual yang mencegah mereka menjangkau ke seluruh mesin fisik tempat layanan Anda yang dilindungi dijalankan.
Jika layanan Anda yang dilindungi tidak begitu berharga untuk dapat memerintahkan langkah-langkah seperti itu, pergi dengan apa pun kunci toko terenkripsi OS memberi Anda: Windows, Linux, dan OSX memiliki implementasi keyring.
sumber
Dalam pikiran saya, satu-satunya cara untuk menjaga ini sepenuhnya aman adalah memiliki kunci / kata sandi yang dienkripsi dengan frasa sandi untuk membuka kunci. Dengan cara ini frasa sandi harus diberikan untuk setiap awal atau penggunaan rahasia .. Tidak terlalu berguna.
Cara lain mungkin memiliki sistem keamanan menjadi akun basis data itu sendiri. Tidak terlalu terukur ...
Jika setiap pengguna pada suatu sistem memiliki akun DB sendiri, dan akun itu adalah premade sehingga aplikasi tersebut tidak memiliki hak untuk membuat akun di DB atas nama pengguna, Anda bisa saja cukup dekat. Juga bukan solusi yang baik, jadi saya kira Anda harus memiliki akses baca yang sangat terbatas pada file-file konfigurasi dan mempercayai pengguna-super Anda.
sumber