加密在 >5.6.0 中不起作用

Encryption not works in >5.6.0

我已经创建了自己的加密 class,使用 mcrypt_encrypt 工作正常,但 mcrypt_decrypt 没有按预期工作。所以这里是下面的代码

error_reporting(1);
ini_set('display_errors', 1);

class Encryption {

    private $key = "myKeyIs";
    protected $iv_size;
    protected $iv;

    public function __construct(){
        $this->iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $this->iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    }

    public function encryptData($input) {
        $input = $input;
        $output = $this->encrypt($input);
        return $output;
    }

    public function decryptData($input) {
        $input = base64_decode($input);
        $output = $this->decrypt($input);
        return $output;
    }

    public function decrypt($string) {
        $string = base64_decode($string);
        # retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
        $iv_dec = substr($string, 0, $this->iv_size);

        # retrieves the cipher text (everything except the $iv_size in the front)
        $string = substr($string, $this->iv_size);

        # may remove 00h valued characters from end of plain text
        $output = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key,
                                        $string, MCRYPT_MODE_CBC, $iv_dec);
        return $output;
    }

    public function encrypt($string) {

        $output = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key,
                                 $string, MCRYPT_MODE_CBC, $this->iv);

        # prepend the IV for it to be available for decryption
        $output = $this->iv . $output;

        # encode the resulting cipher text so it can be represented by a string
        $output = base64_encode($output);

        return $output;
    }

}

$test = new Encryption();
$encrypted  = $test->encryptData("Vicky");
echo $encrypted."\n";
echo $test->decryptData($encrypted);

输出

hCaIoMokbIjLlnFnlrS3Iw==
�M����+�=�l�

现在问题是

  1. 为什么没有按预期解密?
  2. 为什么它不输出高于 PHP 5.6.0 版本的任何文本。你可以 检查 here 版本输出。

我发现了一些错误,它在 5.3.29

以上的 PHP 版本中运行良好
<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

class Encryption {

    private $key;
    protected $iv_size;
    protected $iv;

    public function __construct() {
        # --- ENCRYPTION ---
        # the key should be random binary, use scrypt, bcrypt or PBKDF2 to
        # convert a string into a key
        # key is specified using hexadecimal
        $this->key = pack("H*", "myKeyIsGreaterth2nanndbestofall04nkdsdffsd546754sdfvsdg6efflsdfs");
        # create a random IV to use with CBC encoding
        $this->iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $this->iv = mcrypt_create_iv($this->iv_size, MCRYPT_RAND);
    }

    public function encryptData($input) {
        $output = $this->encrypt($input);
        return $output;
    }

    public function decryptData($input) {
        $input = base64_decode($input);
        $output = $this->decrypt($input);
        return $output;
    }

    protected function decrypt($string) {

        # retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
        $iv_dec = substr($string, 0, $this->iv_size);

        # retrieves the cipher text (everything except the $iv_size in the front)
        $string = substr($string, $this->iv_size);

        # may remove 00h valued characters from end of plain text
        $output = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $string, MCRYPT_MODE_CBC, $iv_dec);

        return $output;
    }

    protected function encrypt($string) {
        # creates a cipher text compatible with AES (Rijndael block size = 128)
        # to keep the text confidential 
        # only suitable for encoded input that never ends with value 00h
        # (because of default zero padding)
        $output = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $string, MCRYPT_MODE_CBC, $this->iv);

        # prepend the IV for it to be available for decryption
        $output = $this->iv . $output;

        # encode the resulting cipher text so it can be represented by a string
        $output = base64_encode($output);

        # === WARNING ===
        # Resulting cipher text has no integrity or authenticity added
        # and is not protected against padding oracle attacks.

        return $output;
    }

}

$test = new Encryption();
$encrypted = $test->encryptData("Vicky");
echo "This is encrypted text of a string Vicky  $encrypted \n";
echo "This is decrypted text ".$test->decryptData($encrypted);

我所做的更新如下

  1. error_reporting(E_ALL); 而不是 error_reporting(1);
  2. Used pack function for key // 如果你不想使用 pack 你可以简单地使用 key Size of 16, 24 or 32
  3. mcrypt_create_iv($iv_size, 更新为 mcrypt_create_iv($this->iv_size,
  4. decrypt 函数中删除了额外的 base64_decode($string);

现在可以使用了,只需更新您自己的密钥

Demo