【问题标题】:PHP MCrypt decryption fails unless using AES-256除非使用 AES-256,否则 PHP MCrypt 解密会失败
【发布时间】:2015-11-22 03:44:07
【问题描述】:

我写了一个类来加密和解密字符串,但是除了MCRYPT_RIJNDAEL_256,我不能使用任何密码。该程序总是报告消息已损坏。我该如何解决?

我测试失败的密码是MCRYPT_RIJNDAEL_128MCRYPT_RIJNDAEL_192MCRYPT_BLOWFISHMCRYPT_SERPENTMCRYPT_TWOFISH

这是我的代码:

class Crypt {
    private $masterKey;
    private $subKey;
    private $cipher = MCRYPT_RIJNDAEL_256 ;
    private $cipherMode = MCRYPT_MODE_CFB;
    //private $hashAlog = 'sha256';

    public function __construct($masterKey) {
        $this->masterKey = $masterKey;
    }

    public function setKey($masterKey) {
        $this->__construct($masterKey);
    }

    public function encrypt($message) {
        $iv = mcrypt_create_iv($this->getIVSize());
        $hmac = $this->signMsg($message);
        $this->genSubKey($iv);
        $cipherText = mcrypt_encrypt($this->cipher, $this->subKey, $message, $this->cipherMode, $iv);
        $cipherText = $iv . $hmac . $cipherText;
        return base64_encode($cipherText);
    }

    public function decrypt($enc_message) {
        $mixedMsg = base64_decode($enc_message);
        $iv = substr($mixedMsg, 0, $this->getIVSize());
        $this->genSubKey($iv);
        $hmac = substr($mixedMsg, $this->getIVSize(), strlen($this->signMsg(null)));
        $cipherText = substr($mixedMsg, $this->getIVSize() + strlen($this->signMsg(null)));
        $message = mcrypt_decrypt($this->cipher, $this->subKey, $cipherText, $this->cipherMode, $iv);
        if(!$message)
            die("Decrypt Error!");
        if($hmac != $this->signMsg($message))
            die("Message Corrupted");
        return $message;
    }

    private function genSubKey($iv) {
        $this->subKey = hash_pbkdf2("sha256", $this->masterKey, $iv, 50000, $this->getKeySize());
    }

    private function getKeySize() {
        return mcrypt_get_key_size($this->cipher, $this->cipherMode);
    }

    private function getIVSize() {
        return mcrypt_get_iv_size($this->cipher, $this->cipherMode);
    }

    private function signMsg($message) {
        return hash_hmac("sha512", $message, $this->masterKey, true);
    }
}

【问题讨论】:

  • 但是我已经将长度限制为密钥大小,真的需要吗?
  • 不,您没有限制$subKey 的长度。它的长度是原来的两倍,因为hash_pbkdf2() 默认输出十六进制编码字节。您需要将 raw_output 设置为 true。
  • 好的问题解决了,我会更新它作为答案。
  • 我不知道为什么MCRYPT_RIJNDAEL_256 会起作用而其他不起作用,但我不得不说MCRYPT_RIJNDAEL_256 不是AES-256。 AES 中的 256 表示密钥大小,但 Rijndael 中的 256 表示块大小。 AES 仅针对 128 位的固定块大小定义。
  • 哦,我明白了,我把它们弄混了。我也不知道为什么会这样。

标签: php encryption mcrypt


【解决方案1】:

问题是由genSubKey函数中的hash_pbkdf2函数引起的。由于hash_pbkdf2 将输出十六进制编码的字符串,因此它将是密钥大小的两倍。为了解决这个问题,我们需要将true 作为附加参数传递给它,让它输出原始字节并适应密钥大小。

这是更正后的代码:

private function genSubKey($iv) {
    $this->subKey = hash_pbkdf2("sha256", $this->masterKey, $iv, 50000, $this->getKeySize(), true);
}

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 2014-12-24
    • 2014-09-12
    • 2014-06-28
    相关资源
    最近更新 更多