Beberapa tahun yang lalu saya menghadiri Laracon EU di mana Marcus Bointon memberikan ceramah hebat tentang Crypto dalam PHP 7. 2. Saya meninggalkan pembicaraan dengan apresiasi yang jauh lebih besar untuk betapa rumitnya kriptografi, tetapi juga untuk bagaimana PHP membuat enkripsi lebih mudah diakses berkat pengenalan Sodium. Enkripsi data dalam PHP sangat penting untuk pekerjaan saya di SpinupWP, panel kontrol server berbasis cloud dengan akses root ke ribuan server dan situs, dan saya pikir akan berguna untuk membagikan apa yang telah saya pelajari sejak saat itu. Bersiaplah, karena ini bisa menjadi perjalanan yang bergelombang Show
Jenis EnkripsiAda berbagai metode enkripsi berbeda yang digunakan saat ini, yang paling umum adalah hashing, enkripsi kunci rahasia, dan enkripsi amplop. Selain itu, setiap metode enkripsi memiliki banyak algoritme atau cipher untuk dipilih (masing-masing dengan kekuatan dan kelemahannya sendiri). Pada artikel ini, kita akan melihat penerapan ketiga metode enkripsi HashingAlgoritme hashing mengambil nilai input dan mengubahnya menjadi output dengan panjang tetap yang dikenal sebagai "pencernaan pesan", "nilai hash", atau sekadar "hash". Hashing adalah satu cara saja, yang berarti bahwa satu-satunya cara untuk memvalidasi keluaran hash adalah meneruskan nilai asli ke algoritme hashing dan membandingkan hasilnya. Ini membuat hashing sempurna untuk menyimpan kata sandi pengguna Perlu dicatat bahwa hashing bukanlah solusi antipeluru dan tidak semua algoritme hashing sama. Pertimbangkan MD5 dan SHA1 yang cepat dan efisien, menjadikannya ideal untuk checksumming dan verifikasi file. Namun, kecepatannya membuat mereka tidak cocok untuk hashing kata sandi pengguna Dengan kekuatan komputasi CPU/GPU modern dan komputasi awan saat ini, kata sandi yang di-hash dapat diretas dengan kekerasan dalam hitungan menit. Ini cukup sepele untuk dengan cepat menghasilkan miliaran hash MD5 dari kata-kata acak hingga ditemukan kecocokan, sehingga mengungkap kata sandi teks biasa asli. Sebagai gantinya, algoritma hashing yang lebih lambat seperti bcrypt atau Argon2 harus digunakan Sementara kata sandi hash yang dihasilkan oleh algoritme apa pun pasti akan mengaburkan data asli dan memperlambat calon penyerang, kami sebagai pengembang harus berusaha untuk menggunakan algoritme terkuat yang tersedia. Untungnya, PHP membuatnya mudah berkat 4 _Fungsi 4 tidak hanya menggunakan algoritme hashing satu arah yang aman, tetapi juga secara otomatis menangani dan mencegah serangan saluran samping berbasis waktu. Fungsi menerima _6 untuk dienkripsi, dan 7 algoritma hashing. Mulai dari PHP5. 5, bcrypt ( 8), yang didasarkan pada cipher Blowfish, akan digunakan sebagai algoritme hashing default. Versi selanjutnya dari PHP memperkenalkan Argon2 (PHP 7. 2) dan Argon2id (PHP 7. 3) algoritma, tetapi bcrypt masih menjadi default. Faktanya, selain peningkatan fungsi _4, opsi yang tersedia dianggap sangat aman sehingga tidak ada algoritme baru yang diperkenalkan ke bahasa untuk PHP 8. 0 atau PHP8. 1Dimungkinkan untuk menggunakan Argon2 atau Argon2id, jika versi PHP Anda telah dikompilasi dengan dukungan Argon2, dengan meneruskan konstanta 0 atau 1 sebagai argumen 7 dari fungsi 4. Untuk memeriksa algoritme mana yang didukung di host web Anda, Anda dapat meluncurkan mode interaktif PHP dari baris perintah server, dan menjalankan fungsi 4. Di bawah ini adalah contoh output dari perintah tersebut di server SpinupWP standar, di mana ketiga opsi tersedia
Memverifikasi kata sandi pengguna juga merupakan proses yang sepele berkat fungsi 5. Cukup berikan kata sandi teks biasa yang diberikan oleh pengguna dan bandingkan dengan hash yang disimpan, seperti itu
Perhatikan bagaimana verifikasi kata sandi dilakukan di PHP. Jika Anda menyimpan kredensial pengguna dalam basis data, Anda mungkin cenderung melakukan hash kata sandi yang dimasukkan saat masuk dan kemudian melakukan kueri SQL basis data, seperti itu
Pendekatan ini rentan terhadap serangan saluran samping dan harus dihindari. Alih-alih, kembalikan pengguna lalu periksa hash kata sandi di PHP
Meskipun hashing bagus untuk mengenkripsi kata sandi, itu tidak berfungsi untuk data arbitrer yang perlu diakses aplikasi kita tanpa campur tangan pengguna. Mari pertimbangkan aplikasi penagihan, yang mengenkripsi informasi kartu kredit pengguna, biasanya disimpan dari formulir HTML. (Mengingat persyaratan kepatuhan hukum dan PCI yang terkait, kami tidak menyarankan untuk membuat aplikasi penagihan Anda sendiri, tetapi gunakan sesuatu seperti Stripe. Kami hanya menggunakan ini sebagai contoh). Setiap bulan aplikasi kami harus menagih pengguna untuk penggunaan bulan sebelumnya. Hashing data kartu kredit tidak akan berfungsi karena aplikasi kami harus dapat mendekripsi data hash yang, seperti yang kami tunjukkan sebelumnya, tidak mungkin dilakukan dengan hashing Enkripsi kunci rahasia untuk menyelamatkan Enkripsi Kunci RahasiaEnkripsi kunci rahasia (atau enkripsi simetris seperti yang juga dikenal) menggunakan satu kunci untuk mengenkripsi dan mendekripsi data. Di masa lalu PHP mengandalkan mcrypt dan openssl untuk enkripsi kunci rahasia. PHP 7. 2 memperkenalkan Sodium, yang lebih modern dan secara luas dianggap lebih aman. Jika Anda menjalankan versi PHP yang lebih lama, Anda dapat menginstal Sodium melalui Perpustakaan Komunitas Ekstensi PHP alias PECL Untuk mengenkripsi nilai, pertama-tama Anda memerlukan kunci enkripsi, yang dapat dibuat menggunakan fungsi 6
Anda juga dapat menggunakan fungsi _7 dengan konstanta bilangan bulat 8 untuk panjang kunci, tetapi menggunakan 6 memastikan bahwa panjang kunci selalu benar (i. e. tidak terlalu pendek), dan lebih mudah
Either way, Anda biasanya hanya akan melakukan ini sekali dan menyimpan hasilnya sebagai variabel lingkungan. Ingatlah bahwa kunci ini harus dirahasiakan dengan cara apa pun. Jika kuncinya pernah dikompromikan, data apa pun juga dienkripsi dengan menggunakannya Untuk mengenkripsi nilai asli, teruskan ke fungsi 0 dengan 1 dan 2 yang dihasilkan. Untuk membuat nonce gunakan fungsi _7, dengan konstanta integer 4 untuk panjang nonce, karena nonce yang sama tidak boleh digunakan kembali
Ini menimbulkan masalah karena kita membutuhkan nonce untuk mendekripsi nilainya nanti. Untungnya, nonce tidak harus dirahasiakan sehingga kita dapat menambahkannya ke 5 lalu 6 nilainya sebelum menyimpannya ke database
Ini akan membuat string yang disandikan base64 dengan panjang 76 karakter Saat mendekripsi nilai, lakukan sebaliknya, dimulai dengan mendekode string yang disandikan base64 0Karena kita mengetahui panjang nonce ( 4) kita dapat mengekstraknya menggunakan 8 sebelum mendekripsi nilainya _1Itu semua yang ada untuk enkripsi kunci rahasia di PHP, terima kasih kepada Sodium Enkripsi AmplopSementara pendekatan yang diuraikan di atas tentu saja merupakan langkah ke arah yang benar, itu masih membuat data kita rentan jika kunci rahasia disusupi. Mari pertimbangkan pengguna jahat yang mendapatkan akses ke server yang menghosting aplikasi kita. Mereka tidak akan berkeliaran di server untuk mendekripsi data sensitif apa pun. Sebaliknya, mereka akan membuat salinan data dan semua file yang relevan ke infrastruktur mereka sendiri dan bekerja untuk menemukan kunci rahasia kami yang kami gunakan untuk mengenkripsi data. Ini membuat data kami benar-benar terbuka Solusi sederhananya adalah tidak menyimpan kunci rahasia kita di lokasi yang sama dengan data terenkripsi, tetapi ini menimbulkan masalah. Bagaimana kami mengenkripsi dan mendekripsi sesuai permintaan? . Perusahaan yang menawarkan infrastruktur cloud seperti AWS dan Google masing-masing memiliki penawarannya sendiri. Sebagai tutorial singkat, kami akan berfokus pada Cloud KMS Google KMS Google CloudCloud KMS adalah layanan yang disediakan oleh Google untuk menghosting kunci kriptografi dengan aman. Ini menyediakan berbagai fitur berguna seputar penyimpanan kunci, termasuk rotasi kunci otomatis dan penghancuran kunci tertunda. Namun, kami terutama memperhatikan penyimpanan kunci rahasia kami secara terpisah dari aplikasi kami Untuk membuatnya lebih aman, kami akan menggunakan teknik yang dikenal sebagai enkripsi amplop. Pada dasarnya, enkripsi amplop melibatkan enkripsi kunci dengan kunci lain. Kami melakukan ini karena dua alasan
Alih-alih mengirimkan data teks biasa kami ke Cloud KMS, kami akan membuat kunci enkripsi unik setiap kali kami menulis data sensitif ke database. Kunci ini dikenal sebagai kunci enkripsi data (DEK), yang akan digunakan untuk mengenkripsi data kita. DEK kemudian dikirim ke Cloud KMS untuk dienkripsi, yang mengembalikan kunci-kunci enkripsi (dikenal sebagai KEK). Terakhir, KEK disimpan berdampingan di database di sebelah data terenkripsi dan DEK dihancurkan. Prosesnya terlihat seperti itu
Saat mendekripsi data, prosesnya dibalik
Cloud KMS dan PHPSeperti kebanyakan layanan Google Cloud, ada yang bisa kita gunakan dalam aplikasi PHP kita. Dokumentasi Cloud KMS cukup lengkap, tetapi saya sarankan untuk memulai dengan panduan Quickstart dan panduan Otentikasi, yang membawa Anda melalui semua persyaratan Persyaratan Cloud KMSPertama, Anda perlu membuat akun Google Cloud dan membuat project Google Cloud baru. Kemudian Anda mengaktifkan Cloud KMS API dan menginstal serta menginisialisasi Cloud SDK. Langkah ini memungkinkan Anda menjalankan alat command line _9, yang Anda gunakan untuk membuat kunci Cloud KMS yang merupakan bagian dari keyring Cloud KMS, dan ada di lokasi Cloud KMS. Terakhir, Anda perlu membuat , memberikan izin ke akun layanan berdasarkan proyek, lalu menyimpan kredensial akun layanan dalam file kredensial lokalMeskipun ini sepertinya banyak pekerjaan yang harus disiapkan, dokumen Google Cloud sangat membantu dalam memandu Anda melalui langkah-langkahnya Implementasi Cloud KMS PHPDengan mengingat hal ini, saya telah membuat kelas pembantu yang sangat sederhana untuk melakukan enkripsi amplop, yang menggunakan Google Cloud KMS SDK. Saya tidak akan mempertimbangkan kode siap-produksi ini, karena dapat menggunakan beberapa penanganan kesalahan yang lebih baik, tetapi ini memberi Anda tempat untuk memulai. Kelas helper ini menggunakan versi terbaru dari Google Cloud KMS SDK, yang saat ini berada di versi 1. 12 _2Anda akan melihat bahwa metode enkripsi dan dekripsi yang sebenarnya hampir identik dengan implementasi kunci rahasia yang diperkenalkan di atas. Namun perbedaannya adalah kami sekarang menggunakan beberapa kunci enkripsi. Mari kita lihat kelas helper beraksi Penggunaan KeyManagerUntuk memanfaatkan kelas helper ini, Anda harus memulai proyek baru dengan dukungan Composer, menginstal paket 0, dan memastikan untuk mewajibkan autoloader Composer. Anda kemudian perlu menyiapkan konstanta 1, menggunakan file kredensial AndaTerakhir, Anda perlu menyiapkan variabel _2, 3, 4 dan 5, yang Anda cocokkan nilainya saat Anda. Anda kemudian dapat membuat instance baru dari kelas KeyManager, dan menggunakannya untuk enkripsi dan dekripsi _3Jika Anda ingin melihat kode ini beraksi, saya telah membuat repositori GitHub yang mengatur segalanya untuk penerapan sederhana ini Jika penyerang menyusupi sistem kami, mereka masih dapat memperoleh akses ke implementasi Cloud KMS API kami, dan menggunakannya untuk mendekripsi data terenkripsi yang mungkin telah mereka salin. Jika demikian, Anda mungkin bertanya-tanya bagaimana enkripsi amplop lebih aman daripada enkripsi kunci rahasia biasa? Perbedaan utama (permainan kata-kata) adalah bahwa akses KMS API dapat dicabut, sehingga mencegah penyerang mendekripsi data apa pun yang telah mereka buat. Dengan enkripsi kunci rahasia reguler di mana satu kunci lokal dikompromikan, Anda tidak memiliki kemewahan itu. Penyerang memiliki seluruh waktu di dunia untuk mendekripsi data sensitif Anda, menggunakan kunci lokal. Enkripsi amplop bukanlah solusi yang sempurna, tetapi tentu saja menurunkan risiko pelanggaran data WordPress dan Data SensitifPertanyaan umum yang saya lihat di kalangan pengembang WordPress adalah; . Biasanya, ini adalah plugin atau tema yang harus dapat mengakses beberapa API pihak ketiga (misalnya layanan MailChimp atau AWS), yang diautentikasi menggunakan kunci akses API dan terkadang rahasia kunci akses. Salah satu contohnya adalah WP Offload Media kami sendiri, yang memerlukan kredensial akses ke penyedia penyimpanan di luar situs Anda Umumnya, ada dua opsi utama yang tersedia untuk mengimplementasikan detail akses ini
Kenyataannya adalah, apa pun yang Anda lakukan, jika kode Anda dapat membaca rahasianya, penyerang yang termotivasi pun dapat melakukannya. Seperti yang telah kita diskusikan, bahkan enkripsi amplop tidak sepenuhnya aman, dan sebagai pengembang plugin, Anda memiliki sedikit kendali atas metode enkripsi yang tersedia untuk pemilik situs. Menurut pendapat saya, lebih baik mengedukasi pengguna Anda tentang keamanan. Pastikan Anda memiliki dokumentasi yang dapat mereka gunakan untuk menonaktifkan akses API pihak ketiga di sumbernya jika terjadi pelanggaran. Pastikan dokumentasi Anda mencakup aspek-aspek seperti cara membatasi kemampuan baca atau tulis pada layanan pihak ketiga. Misalnya, kami baru saja memperbarui dokumentasi penyedia penyimpanan cadangan SpinupWP kami dengan detail tentang caranya Jika Anda bekerja dengan pemilik situs, ajari mereka untuk selalu memperbarui inti, plugin, dan tema WordPress, serta versi PHP mereka, untuk mencegah kerentanan; . Jika mereka perlu mengakses server, pastikan mereka menggunakan autentikasi kunci SSH dan SFTP untuk mengelola file Tidak apa-apa mengganti kunci rumah Anda setelah seseorang mencuri kunci Anda, tetapi lebih baik jangan pernah kunci Anda dicuri sejak awal. MembungkusKeamanan dan enkripsi data adalah subjek yang sangat luas dan saya hanya membahas beberapa cara untuk melindungi data sensitif menggunakan PHP. Namun pada akhirnya, enkripsi apa pun yang Anda terapkan masih rentan terhadap serangan, tingkat risikonya bervariasi. Mengetahui jenis yang berbeda berarti Anda dapat memilih untuk menerapkannya pada berbagai tingkat kode aplikasi Anda, bergantung pada sensitivitas data Anda Tindakan pencegahan apa yang Anda lakukan? Catatan ini telah diposting di WP Migrate DB Pro, Pengembangan Plugin dan menandai Pengembangan, Keamanan, PHP, Enkripsi, Hashing, Kata Sandi tentang PenulisAshley KayaAshley adalah Laravel dan Vue. Pengembang js dengan minat dalam perkakas untuk hosting WordPress, kinerja server, dan keamanan. Sebelum bergabung dengan Delicious Brains, Ashley bertugas di Royal Air Force sebagai Teknisi TIK @A5hleyRich ashleyrich. com
|