Rumah > Soal Jawab > teks badan
Saya ingin menambah baik pemalam WordPress tertentu yang menggunakan "mcrypt" yang kini usang. Sebaliknya, saya ingin menggunakan perpustakaan OpenSSL untuk menyulitkan data yang diserahkan, tetapi semasa proses penyulitan saya menghadapi masalah, iaitu: fungsi openssl_encrypt mengembalikan nilai yang berbeza daripada mcrypt_encrypt, sistem yang saya sambungkan tidak mengembalikan data saya dengan yang betul nilai, dan Pemiliknya tidak boleh menghantar saya log kandungan yang saya muat naik kepadanya :(
Saya telah mencari di seluruh internet tetapi masih belum menemui penyelesaian. Saya mengesyaki masalahnya adalah dengan padding, tetapi saya tidak dapat mencari penyelesaian. boleh awak tolong?
Berikut ialah perubahan jelas dalam objek PHP saya $kata laluan, $salt dan $iv
class EncryptDebug{ private $algo = 'sha1'; private $password = 'ab4232goodcf423484422c90c3e4aa7c'; private $salt = 'ascastas54490a31'; private $iv = '8947da32awl55kwj' private $lenght = 16; private function generate_key(){ return hash_pbkdf2( $this->algo , $this->password , $this->salt, 100, $this->lenght, true ); } public function encryptSSL($plaintext){ $key = $this->generate_key(); $ciphertext = base64_encode(openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_ZERO_PADDING, $this->iv)); return str_replace('+', '%2B', $ciphertext); } public function encryptMCRYPT($plaintext){ $key = $this->generate_key(); $ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $this->iv)); return str_replace('+', '%2B', $ciphertext); } }
Terlupa untuk menyebut: OPENSSL_ZERO_PADDING mengembalikan ralat. Menggunakan OPENSSL_RAW_DATA saya boleh mendapatkan hasil yang serupa dengan mcrypt_encrypt tetapi dengan pengakhiran yang berbeza, contohnya:
OpenSSL: rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG%2BVPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8WcNzMJ868026TkUxcYJMrQ==
MCRYPT: rPzVvF7gaPMA4ADAjHUW8Wy1ThTJG%2BVPdcz5iKAkAwrDTTFTcOpWgWOCh9l9JFZ8UGVfF091Q9bY61mTRg%2BBSg==
P粉0218547772023-09-10 15:21:03
Dicapai dengan bendera encryptSSL()
中,当前使用 Base64 编码两次,默认情况下一次是显式编码,一次是隐式编码。因此,必须删除其中一种 Base64 编码,无论是显式编码还是隐式编码。前者是通过删除 base64_encode()
调用来实现的,后者是通过设置 OPENSSL_RAW_DATA
.
Selain itu, mcrypt menggunakan padding sifar dan PHP/OpenSSL menggunakan padding PKCS#7. Oleh itu, untuk mendapatkan hasil yang sama seperti encryptSSL()
给出与 encryptMCRYPT()
, zero padding mesti digunakan. Memandangkan PHP/OpenSSL tidak menyokong padding sifar, padding PKCS#7 mesti dilumpuhkan (menggunakan bendera OPENSSL_ZERO_PADDING) dan padding sifar mesti dilaksanakan secara eksplisit >.
Keseluruhan:
$ciphertext = openssl_encrypt($this->zeroPad($plaintext, 16), 'AES-128-CBC', $key, OPENSSL_ZERO_PADDING, $this->iv); // remove base64_encode(), zero pad plaintext, disable PKCS#7 padding
dengan:
protected function zeroPad($text, $bs) { $pad = $bs - strlen($text) % $bs; return ($pad < 16) ? $text . str_repeat("rrreee", $pad) : $text; }
Dengan perubahan ini, kedua-dua fungsi memberikan hasil yang sama.
Sila ambil perhatian bahawa padding sifar kurang dipercayai daripada padding PKCS#7.
Keselamatan:
Sila ambil perhatian bahawa IV statik dan garam statik adalah pepijat. Sebaliknya, kedua-duanya akan dijana secara rawak dan diserahkan kepada pihak penyahsulitan bersama-sama dengan teks sifir, biasanya dalam gabungan (tidak ada rahsia).
Selain itu, nombor lelaran 100 untuk PBKDF2 biasanya terlalu kecil.