【问题标题】:Encryption not works in >5.6.0加密在 >5.6.0 中不起作用
【发布时间】:2015-11-23 05:07:02
【问题描述】:

我创建了自己的加密类,使用 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 的版本输出。

【问题讨论】:

  • 问题是你使用了error_reporting(1),它并没有达到你预期的效果。它将禁用几乎所有错误。您正在寻找error_reporting(E_ALL)。这样,您应该会看到一条警告,说明调用失败的原因(错误的密钥大小)。

标签: php encryption php-5.6


【解决方案1】:

我发现了一些错误,它在 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你可以简单地使用16, 24 or 32的键大小
  3. mcrypt_create_iv($iv_size, 更新为mcrypt_create_iv($this-&gt;iv_size,
  4. decrypt 函数中删除了额外的 base64_decode($string);

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

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多