代码之家  ›  专栏  ›  技术社区  ›  Hartman

除非使用AES-256,否则PHP MCrypt解密失败

  •  1
  • Hartman  · 技术社区  · 9 年前

    我已经编写了一个类来加密和解密字符串,但除了 MCRYPT_RIJNDAEL_256 。程序始终报告消息已损坏。我该如何修复它?

    我测试的失败密码是 MCRYPT_RIJNDAEL_128 MCRYPT_RIJNDAEL_192 MCRYPT_BLOWFISH MCRYPT_SERPENT MCRYPT_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);
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   2awm366    8 年前

    问题是由 hash_pbkdf2 中的函数 genSubKey 作用自从 哈希_pbkdf2 将输出十六进制编码的字符串,它将是密钥大小的两倍。要解决这个问题,我们需要通过 true 作为它的附加参数,让它输出原始字节并适合密钥大小。

    以下是更正的代码:

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