mcrypt sudah tidak digunakan lagi, apa alternatifnya?

103

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.

Piet
sumber
9
Mengapa Anda perlu mengenkripsi / mendekripsi kata sandi? Mengapa tidak hanya hash password_hashdan memverifikasinya password_verify?
Jangan Panik
3
"kata sandi yang dienkripsi juga harus dapat didekripsi" - mengapa? kedengarannya tidak terlalu aman. Ada alasan khusus?
Funk Forty Niner
24
"karena pelanggan saya ingin memiliki opsi untuk 'memulihkan' sandi mereka tanpa membuat yang baru." - Itu tidak aman dan mereka harus diberi opsi untuk menyetel ulang sandi mereka.
Funk Forty Niner
4
Jangan mengenkripsi password , ketika penyerang mendapatkan DB dia juga akan mendapatkan kunci enkripsi. Iterasi melalui HMAC dengan garam acak selama sekitar 100 milidetik dan simpan garam dengan hash. Gunakan fungsi seperti password_hash, PBKDF2, Bcrypt dan fungsi serupa. Intinya adalah membuat penyerang menghabiskan banyak waktu untuk menemukan kata sandi dengan kekerasan.
zaf
2
Dari manual php -> Fungsi ini TIDAK DIGUNAKAN LAGI pada PHP 7.1.0. Mengandalkan fungsi ini sangat tidak disarankan. Alternatifnya adalah natrium -> php.net/manual/en/book.sodium.php
MarcoZen

Jawaban:

47

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:

  • Gunakan Libsodium - Ekstensi PHP
  • Jika Anda tidak dapat menggunakan Libsodium, gunakan defuse / php-encryption - Kode PHP langsung
  • Jika Anda tidak dapat menggunakan Libsodium atau defuse / php-encryption, gunakan OpenSSL - Banyak server sudah menginstal ini. Jika tidak, dapat dikompilasi dengan --with-openssl [= DIR]
Phil
sumber
1
Pertama-tama harus mencoba openssl karena ini sangat umum, di mana libsodium tidak. PHP mentah tidak boleh digunakan kecuali semua ekstensi asli tidak ada jika pertanyaan
JSON
Meskipun openssl sangat umum, tampaknya php 7 akan menggunakan libsodium untuk inti kriptografi securityintelligence.com/news/…
shadi
1
Perhatikan ada pustaka bernama Sodium-compat( github.com/paragonie/sodium_compat ) yang bekerja di PHP> = 5.2.4
RaelB
30

Seperti yang disarankan oleh @rqLizard , Anda dapat menggunakan openssl_encrypt/ openssl_decryptfungsi 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 :

Jika Anda menulis kode untuk mengenkripsi / mengenkripsi data pada tahun 2015, Anda harus menggunakan openssl_encrypt()dan openssl_decrypt(). Pustaka yang mendasari ( libmcrypt) telah ditinggalkan sejak 2007, dan berkinerja jauh lebih buruk daripada OpenSSL (yang memanfaatkan AES-NIprosesor modern dan aman untuk pengaturan waktu cache).

Juga, MCRYPT_RIJNDAEL_256bukan AES-256, ini adalah varian berbeda dari cipher blok Rijndael. Jika Anda ingin AES-256di mcrypt, Anda harus menggunakan MCRYPT_RIJNDAEL_128dengan kunci 32-byte. OpenSSL membuatnya lebih jelas mode mana yang Anda gunakan (yaitu aes-128-cbcvs aes-256-ctr).

OpenSSL juga menggunakan padding PKCS7 dengan mode CBC daripada padding byte NULL mcrypt. Dengan demikian, mcrypt lebih cenderung membuat kode Anda rentan terhadap serangan oracle padding daripada OpenSSL.

Terakhir, jika Anda tidak mengautentikasi ciphertext Anda (Encrypt Then MAC), Anda salah melakukannya.

Bacaan lebih lanjut:

Contoh kode

Contoh 1

Contoh Enkripsi Terautentikasi AES dalam mode GCM untuk PHP 7.1+

<?php
//$key should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
    //store $cipher, $iv, and $tag for decryption later
    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
    echo $original_plaintext."\n";
}
?>

Contoh # 2

Contoh AES Authenticated Encryption untuk PHP 5.6+

<?php
//$key previously generated safely, ie: openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );

//decrypt later....
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
{
    echo $original_plaintext."\n";
}
?>

Contoh # 3

Berdasarkan contoh di atas, saya telah mengubah kode berikut yang bertujuan untuk mengenkripsi id sesi pengguna:

class Session {

  /**
   * Encrypts the session ID and returns it as a base 64 encoded string.
   *
   * @param $session_id
   * @return string
   */
  public function encrypt($session_id) {
    // Get the MD5 hash salt as a key.
    $key = $this->_getSalt();
    // For an easy iv, MD5 the salt again.
    $iv = $this->_getIv();
    // Encrypt the session ID.
    $encrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $session_id, MCRYPT_MODE_CBC, $iv);
    // Base 64 encode the encrypted session ID.
    $encryptedSessionId = base64_encode($encrypt);
    // Return it.
    return $encryptedSessionId;
  }

  /**
   * Decrypts a base 64 encoded encrypted session ID back to its original form.
   *
   * @param $encryptedSessionId
   * @return string
   */
  public function decrypt($encryptedSessionId) {
    // Get the MD5 hash salt as a key.
    $key = $this->_getSalt();
    // For an easy iv, MD5 the salt again.
    $iv = $this->_getIv();
    // Decode the encrypted session ID from base 64.
    $decoded = base64_decode($encryptedSessionId);
    // Decrypt the string.
    $decryptedSessionId = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded, MCRYPT_MODE_CBC, $iv);
    // Trim the whitespace from the end.
    $session_id = rtrim($decryptedSessionId, "\0");
    // Return it.
    return $session_id;
  }

  public function _getIv() {
    return md5($this->_getSalt());
  }

  public function _getSalt() {
    return md5($this->drupal->drupalGetHashSalt());
  }

}

ke:

class Session {

  const SESS_CIPHER = 'aes-128-cbc';

  /**
   * Encrypts the session ID and returns it as a base 64 encoded string.
   *
   * @param $session_id
   * @return string
   */
  public function encrypt($session_id) {
    // Get the MD5 hash salt as a key.
    $key = $this->_getSalt();
    // For an easy iv, MD5 the salt again.
    $iv = $this->_getIv();
    // Encrypt the session ID.
    $ciphertext = openssl_encrypt($session_id, self::SESS_CIPHER, $key, $options=OPENSSL_RAW_DATA, $iv);
    // Base 64 encode the encrypted session ID.
    $encryptedSessionId = base64_encode($ciphertext);
    // Return it.
    return $encryptedSessionId;
  }

  /**
   * Decrypts a base 64 encoded encrypted session ID back to its original form.
   *
   * @param $encryptedSessionId
   * @return string
   */
  public function decrypt($encryptedSessionId) {
    // Get the Drupal hash salt as a key.
    $key = $this->_getSalt();
    // Get the iv.
    $iv = $this->_getIv();
    // Decode the encrypted session ID from base 64.
    $decoded = base64_decode($encryptedSessionId, TRUE);
    // Decrypt the string.
    $decryptedSessionId = openssl_decrypt($decoded, self::SESS_CIPHER, $key, $options=OPENSSL_RAW_DATA, $iv);
    // Trim the whitespace from the end.
    $session_id = rtrim($decryptedSessionId, '\0');
    // Return it.
    return $session_id;
  }

  public function _getIv() {
    $ivlen = openssl_cipher_iv_length(self::SESS_CIPHER);
    return substr(md5($this->_getSalt()), 0, $ivlen);
  }

  public function _getSalt() {
    return $this->drupal->drupalGetHashSalt();
  }

}

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_RIJNDAELhanya mendukung padding null non-standar. @faf


Catatan tambahan (dari komentar @zaph):

  • Rijndael 128 ( 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 . @faf
  • Rijndael dengan ukuran blok 256 mungkin kurang aman dibandingkan dengan ukuran blok 128-bit karena yang terakhir memiliki lebih banyak ulasan dan kegunaan. Kedua, interoperabilitas terhalang sementara AES umumnya tersedia, di mana Rijndael dengan ukuran blok 256-bit tidak.
  • Enkripsi dengan ukuran blok berbeda untuk Rijndael menghasilkan data terenkripsi yang berbeda.

    Misalnya, MCRYPT_RIJNDAEL_256(tidak setara dengan AES-256) mendefinisikan varian berbeda dari cipher blok Rijndael dengan ukuran 256-bit dan ukuran kunci berdasarkan kunci yang diteruskan, di mana aes-256-cbcRijndael 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.

kenorb
sumber
1
Secara umum menggunakan Rijndael dengan ukuran blok 256-bit merupakan kesalahan karena pilihan pengembang mcrypt. Rijndael lebih lanjut dengan ukuran blok 256 mungkin kurang aman dibandingkan dengan ukuran blok 128-bit karena yang terakhir memiliki lebih banyak tinjauan dan penggunaan. Selain itu interoperabilitas terhalang sementara AES umumnya tersedia Rijndael dengan ukuran blok 256-bit tidak.
zaf
Mengapa Anda $session_id = rtrim($decryptedSessionId, "\0");? Apakah mungkin untuk openssl_decryptmengembalikan beberapa karakter yang tidak diinginkan pada akhirnya? Bagaimana jika variabel terenkripsi diakhiri dengan 0 (yaitu encrypt("abc0")?
hlscalon
@hiscalon "\0"tidak lain adalah "0"karakter NULL, yang kode ASCII-nya adalah 0x00 (heksadesimal 0).
kiamlaluno
11

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

$decoded = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, ENCRYPT_KEY, $term, MCRYPT_MODE_ECB);

bekerja seperti ini dengan perpustakaan

$rijndael = new \phpseclib\Crypt\Rijndael(\phpseclib\Crypt\Rijndael::MODE_ECB);
$rijndael->setKey(ENCRYPT_KEY);
$rijndael->setKeyLength(256);
$rijndael->disablePadding();
$rijndael->setBlockLength(256);

$decoded = $rijndael->decrypt($term);

* $termdulubase64_decoded

Pentium10
sumber
11

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:

function encrypt($key, $payload) {
  $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
  $encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
  return base64_encode($encrypted . '::' . $iv);
}

Untuk mendekripsi:

function decrypt($key, $garble) {
    list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
    return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
}

Tautan referensi: https://www.shift8web.ca/2017/04/how-to-encrypt-and-execute-your-php-code-with-mcrypt/

Ariston Cordeiro
sumber
Banyak karma baik untukmu teman! Hanya satu hal: jika kata sandi, misalnya, dienkripsi dengan kode lama, kode dekripsi baru tidak akan dapat memverifikasinya. Itu harus disimpan ulang dan dienkripsi dengan kode baru ini.
Lumis
Skrip migrasi sederhana akan menyelesaikan masalah itu. Gunakan cara lama untuk mendekripsi, lalu cara baru untuk mengenkripsi dan menyimpan. Alternatifnya adalah menambahkan bendera ke tabel pengguna dan membuat skrip dalam pengaturan ulang sandi paksa pada semua akun pengguna yang memerlukan perubahan sandi.
cecil merrel alias bringrainfire
8

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.

Ahmet Erkan ÇELİK
sumber
2
Ini sangat membantu, terima kasih. Harus menghapus ekstensi php-mcrypt, dan kemudian ini berfungsi seperti pesona.
DannyB
Saya menginstal mcrypt_compatdengan menjalankan composer require phpseclib/mcrypt_compattetapi saya masih PHP Fatal error: Uncaught Error: Call to undefined function mcrypt_get_key_size() in /app/kohana/classes/Kohana/Encrypt.php:124menggunakan php 7.2.26dan framwork Kohana. Apakah ada langkah lain yang harus dilakukan setelah menginstalnya dengan komposer?
M-Dahab
Mengerti. Anda harus menambahkan require APPPATH . '/vendor/autoload.php';ke bagian bawah bootstrap.php.
M-Dahab
3

Anda harus menggunakan OpenSSL mcryptkarena 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 menentukan OPENSSL_ZERO_PADDINGapakah Anda membutuhkannya. Untuk menggunakan kunci biner 32-byte, Anda dapat menentukan aes-256-cbcmana yang lebih jelas daripada MCRYPT_RIJNDAEL_128.

Berikut adalah contoh kode menggunakan Mcrypt:

Pustaka enkripsi AES-256-CBC tidak terautentikasi yang ditulis di Mcrypt dengan padding PKCS7.

/**
 * This library is unsafe because it does not MAC after encrypting
 */
class UnsafeMcryptAES
{
    const CIPHER = MCRYPT_RIJNDAEL_128;

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = mcrypt_get_iv_size(self::CIPHER);
        $iv = mcrypt_create_iv($ivsize, MCRYPT_DEV_URANDOM);

        // Add PKCS7 Padding
        $block = mcrypt_get_block_size(self::CIPHER);
        $pad = $block - (mb_strlen($message, '8bit') % $block, '8bit');
        $message .= str_repeat(chr($pad), $pad);

        $ciphertext = mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128,
            $key,
            $message,
            MCRYPT_MODE_CBC,
            $iv
        );

        return $iv . $ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = mcrypt_get_iv_size(self::CIPHER);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        $plaintext = mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            $key,
            $ciphertext,
            MCRYPT_MODE_CBC,
            $iv
        );

        $len = mb_strlen($plaintext, '8bit');
        $pad = ord($plaintext[$len - 1]);
        if ($pad <= 0 || $pad > $block) {
            // Padding error!
            return false;
        }
        return mb_substr($plaintext, 0, $len - $pad, '8bit');
    }
}

Dan berikut adalah versi yang ditulis menggunakan OpenSSL:

/**
 * This library is unsafe because it does not MAC after encrypting
 */
class UnsafeOpensslAES
{
    const METHOD = 'aes-256-cbc';

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = openssl_random_pseudo_bytes($ivsize);

        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );

        return $iv . $ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        return openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}

Sumber: Jika Anda Mengetik Kata MCRYPT Ke Kode PHP Anda, Anda Salah .

kenorb
sumber
2

Saya menggunakan ini di PHP 7.2.x, ini berfungsi dengan baik untuk saya:

public function make_hash($userStr){
        try{
            /** 
             * Used and tested on PHP 7.2x, Salt has been removed manually, it is now added by PHP 
             */
             return password_hash($userStr, PASSWORD_BCRYPT);
            }catch(Exception $exc){
                $this->tempVar = $exc->getMessage();
                return false;
            }
        }

lalu autentikasi hash dengan fungsi berikut:

public function varify_user($userStr,$hash){
        try{
            if (password_verify($userStr, $hash)) {
                 return true;
                }
            else {
                return false;
                }
            }catch(Exception $exc){
                $this->tempVar = $exc->getMessage();
                return false;
            }
        }

Contoh:

  //create hash from user string

 $user_password = $obj->make_hash2($user_key);

dan untuk mengotentikasi hash ini gunakan kode berikut:

if($obj->varify_user($key, $user_key)){
      //this is correct, you can proceed with  
    }

Itu saja.

Abdul Rahman
sumber
1

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()dan password_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. Tetapkan PASSWORD_DEFAULTopsi 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.

Thoracius Appotite
sumber
1

Anda harus menggunakan openssl_encrypt()fungsi.

rqLizard
sumber
Apakah openssl encrypt di php 7 sudah "heartbleed"?
TheCrazyProfessor
13
mengapa OP menggunakan openssl_encrypt? Berikan beberapa detail dan latar belakang
Martin
0

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

    openssl genrsa -des3 -out pkey.pem 2048
    (set a password)
    openssl rsa -in pkey.pem -out pkey-pub.pem -outform PEM -pubout
  • 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)

    $pubKey = openssl_get_publickey(file_get_contents('./pkey-pub.pem'));
    openssl_seal($pwd, $sealed, $ekeys, [ $pubKey ]);
    $encryptedPassword = base64_encode($sealed);
    $key = base64_encode($ekeys[0]);

Anda mungkin bisa menyimpan biner mentah.

  • Mendekripsi (menggunakan kunci pribadi)

    $passphrase="passphrase here";
    $privKey = openssl_get_privatekey(file_get_contents('./pkey.pem'), $passphrase);
    // I base64_decode() from my db columns
    openssl_open($encryptedPassword, $plain, $key, $privKey);
    echo "<h3>Password=$plain</h3>";

PS Anda tidak dapat mengenkripsi string kosong ("")

PPS Ini untuk database kata sandi bukan untuk validasi pengguna.

Joshua Goldstein
sumber