Ekstensi mcrypt tidak digunakan lagi akan dihapus di PHP 7.2 menurut komentar yang diposting di sini . Jadi saya mencari cara alternatif untuk mengenkripsi kata sandi.
Sekarang saya menggunakan sesuatu seperti
mcrypt_encrypt(MCRYPT_RIJNDAEL_128, md5($key, true), $string, MCRYPT_MODE_CBC, $iv)
Saya membutuhkan pendapat Anda untuk cara terbaik / terkuat untuk mengenkripsi kata sandi, kata sandi terenkripsi tentu saja harus didukung oleh PHP 7.xx dan juga harus dapat didekripsi karena pelanggan saya ingin memiliki opsi untuk 'memulihkan' kata sandi mereka tanpa membuat yang baru satu.
password_hash
dan memverifikasinyapassword_verify
?Jawaban:
Praktik terbaik untuk mencirikan kata sandi sehingga tidak dapat didekripsi. Ini membuat segalanya sedikit lebih sulit bagi penyerang yang mungkin telah memperoleh akses ke database atau file Anda.
Jika Anda harus mengenkripsi data Anda dan membuatnya dapat didekripsi, panduan untuk mengamankan enkripsi / dekripsi tersedia di https://paragonie.com/white-paper/2015-secure-php-data-encryption . Untuk meringkas tautan itu:
sumber
Sodium-compat
( github.com/paragonie/sodium_compat ) yang bekerja di PHP> = 5.2.4Seperti yang disarankan oleh @rqLizard , Anda dapat menggunakan
openssl_encrypt
/openssl_decrypt
fungsi PHP sebagai gantinya yang menyediakan alternatif yang jauh lebih baik untuk mengimplementasikan AES (The Advanced Encryption Standard) yang juga dikenal sebagai enkripsi Rijndael.Sesuai komentar Scott berikut di php.net :
Bacaan lebih lanjut:
Contoh kode
Contoh 1
Contoh # 2
Contoh # 3
Berdasarkan contoh di atas, saya telah mengubah kode berikut yang bertujuan untuk mengenkripsi id sesi pengguna:
ke:
Untuk memperjelas, perubahan di atas bukanlah konversi yang sebenarnya karena kedua enkripsi menggunakan ukuran blok yang berbeda dan data terenkripsi yang berbeda. Selain itu, padding default berbeda,
MCRYPT_RIJNDAEL
hanya mendukung padding null non-standar. @fafCatatan tambahan (dari komentar @zaph):
MCRYPT_RIJNDAEL_128
) adalah setara dengan AES , namun Rijndael 256 (MCRYPT_RIJNDAEL_256
) tidak AES-256 sebagai 256 menspesifikasikan ukuran blok 256-bit, sedangkan AES hanya memiliki satu ukuran blok: 128-bit. Jadi pada dasarnya Rijndael dengan ukuran blok 256-bit (MCRYPT_RIJNDAEL_256
) telah keliru dinamai karena pilihan oleh pengembang mcrypt . @fafEnkripsi dengan ukuran blok berbeda untuk Rijndael menghasilkan data terenkripsi yang berbeda.
Misalnya,
MCRYPT_RIJNDAEL_256
(tidak setara denganAES-256
) mendefinisikan varian berbeda dari cipher blok Rijndael dengan ukuran 256-bit dan ukuran kunci berdasarkan kunci yang diteruskan, di manaaes-256-cbc
Rijndael dengan ukuran blok 128-bit dengan ukuran kunci 256-bit. Oleh karena itu mereka menggunakan ukuran blok yang berbeda yang menghasilkan data terenkripsi yang sama sekali berbeda karena mcrypt menggunakan nomor tersebut untuk menentukan ukuran blok, di mana OpenSSL menggunakan nomor tersebut untuk menentukan ukuran kunci (AES hanya memiliki satu ukuran blok 128-bit). Jadi pada dasarnya AES adalah Rijndael dengan ukuran blok 128-bit dan ukuran kunci 128, 192 dan 256 bit. Oleh karena itu lebih baik menggunakan AES, yang disebut Rijndael 128 di OpenSSL.sumber
$session_id = rtrim($decryptedSessionId, "\0");
? Apakah mungkin untukopenssl_decrypt
mengembalikan beberapa karakter yang tidak diinginkan pada akhirnya? Bagaimana jika variabel terenkripsi diakhiri dengan 0 (yaituencrypt("abc0")
?"\0"
tidak lain adalah"0"
karakter NULL, yang kode ASCII-nya adalah 0x00 (heksadesimal 0).Implementasi Pure-PHP dari Rijndael ada dengan phpseclib tersedia sebagai paket komposer dan bekerja pada PHP 7.3 (diuji oleh saya).
Ada halaman di dokumen phpseclib, yang menghasilkan kode sampel setelah Anda memasukkan variabel dasar (sandi, mode, ukuran kunci, ukuran bit). Ini menghasilkan yang berikut untuk Rijndael, ECB, 256, 256:
kode dengan mycrypt
bekerja seperti ini dengan perpustakaan
*
$term
dulubase64_decoded
sumber
Sebagaimana dirinci oleh jawaban lain di sini, solusi terbaik yang saya temukan adalah menggunakan OpenSSL. Itu dibangun ke dalam PHP dan Anda tidak memerlukan perpustakaan eksternal apa pun. Berikut contoh sederhananya:
Untuk mengenkripsi:
Untuk mendekripsi:
Tautan referensi: https://www.shift8web.ca/2017/04/how-to-encrypt-and-execute-your-php-code-with-mcrypt/
sumber
Anda dapat menggunakan paket phpseclib pollyfill. Anda tidak dapat menggunakan open ssl atau libsodium untuk mengenkripsi / mendekripsi dengan rijndael 256. Masalah lainnya, Anda tidak perlu mengganti kode apa pun.
sumber
mcrypt_compat
dengan menjalankancomposer require phpseclib/mcrypt_compat
tetapi saya masihPHP Fatal error: Uncaught Error: Call to undefined function mcrypt_get_key_size() in /app/kohana/classes/Kohana/Encrypt.php:124
menggunakan php7.2.26
dan framwork Kohana. Apakah ada langkah lain yang harus dilakukan setelah menginstalnya dengan komposer?require APPPATH . '/vendor/autoload.php';
ke bagian bawahbootstrap.php
.Anda harus menggunakan OpenSSL
mcrypt
karena itu dikembangkan dan dipelihara secara aktif. Ini memberikan keamanan, pemeliharaan, dan portabilitas yang lebih baik. Kedua, ia melakukan enkripsi / dekripsi AES lebih cepat. Ini menggunakan padding PKCS7 secara default, tetapi Anda dapat menentukanOPENSSL_ZERO_PADDING
apakah Anda membutuhkannya. Untuk menggunakan kunci biner 32-byte, Anda dapat menentukanaes-256-cbc
mana yang lebih jelas daripadaMCRYPT_RIJNDAEL_128
.Berikut adalah contoh kode menggunakan Mcrypt:
Dan berikut adalah versi yang ditulis menggunakan OpenSSL:
Sumber: Jika Anda Mengetik Kata MCRYPT Ke Kode PHP Anda, Anda Salah .
sumber
Saya menggunakan ini di PHP 7.2.x, ini berfungsi dengan baik untuk saya:
lalu autentikasi hash dengan fungsi berikut:
Contoh:
dan untuk mengotentikasi hash ini gunakan kode berikut:
Itu saja.
sumber
Seperti yang ditunjukkan, Anda tidak boleh menyimpan kata sandi pengguna Anda dalam format yang dapat didekripsi. Enkripsi yang dapat dibalik menyediakan rute mudah bagi peretas untuk mengetahui kata sandi pengguna Anda, yang mencakup menempatkan akun pengguna Anda di situs lain dalam risiko jika mereka menggunakan kata sandi yang sama di sana.
PHP menyediakan sepasang fungsi yang kuat untuk enkripsi hash satu arah asin acak -
password_hash()
danpassword_verify()
. Karena hash secara otomatis diasinkan secara acak, tidak ada cara bagi peretas untuk menggunakan tabel hash kata sandi yang telah dikompilasi sebelumnya untuk merekayasa ulang kata sandi. TetapkanPASSWORD_DEFAULT
opsi dan versi PHP yang akan datang akan secara otomatis menggunakan algoritma yang lebih kuat untuk menghasilkan hash kata sandi tanpa Anda harus memperbarui kode Anda.sumber
Anda harus menggunakan
openssl_encrypt()
fungsi.sumber
Saya bisa menerjemahkan objek Crypto saya
Dapatkan salinan php dengan mcrypt untuk mendekripsi data lama. Saya pergi ke http://php.net/get/php-7.1.12.tar.gz/from/a/mirror , mengkompilasinya, lalu menambahkan ekstensi ext / mcrypt (configure; make; make install). Saya rasa saya harus menambahkan baris extenstion = mcrypt.so ke php.ini juga. Serangkaian skrip untuk membangun versi perantara dari data dengan semua data tidak terenkripsi.
Bangun kunci publik dan pribadi untuk openssl
Untuk Enkripsi (menggunakan kunci publik) gunakan openssl_seal. Dari apa yang saya baca, openssl_encrypt menggunakan kunci RSA dibatasi hingga 11 byte kurang dari panjang kunci (Lihat http://php.net/manual/en/function.openssl-public-encrypt.php komentar oleh Thomas Horsten)
Anda mungkin bisa menyimpan biner mentah.
Mendekripsi (menggunakan kunci pribadi)
PS Anda tidak dapat mengenkripsi string kosong ("")
PPS Ini untuk database kata sandi bukan untuk validasi pengguna.
sumber