【问题标题】:How to decrypt an encrypted string using openssl_decrypt如何使用 openssl_decrypt 解密加密字符串
【发布时间】:2020-09-17 21:37:29
【问题描述】:

我正在尝试开发一个 php 程序来加密一些以后可以解密的数据。但是,我无法使用 PHP 中的 openssl_decrypt() 方法使用 AES-256-CBC 算法解密数据。加密有效,但是当我尝试解密时,它给了我一个错误:-
hash_equals(): Expected known_string to be a string, bool given on line 44.

我的代码如下:

<?php

class Encryption{
    
    protected $data, $encryption_type, $key, $iv;

    public function __construct(){
        $mydata = "Is this safe";
        $encryption = $this->secured_encryption($mydata);

        // Decrypting data
        $data_to_decrypt = $encryption;
        $this->decrypt_data($data_to_decrypt);
    }

    public function secured_encryption($data){
        $this->data = $data;
        $this->encryption_type = "AES-256-CBC"; // cipher algorithm
        $this->key = ['6d2d823df2e08c0d3cdf70f148998d49', 'fdb3a18c7b0a322fdb3a18c7b0a320d3'];
        $this->iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->encryption_type));
        $encrypted_data = openssl_encrypt($this->data, $this->encryption_type, $this->key[0], OPENSSL_RAW_DATA, $this->iv);
        $final_encryption = hash_hmac('SHA3-512', $encrypted_data, $this->key[1], true);
        $output = base64_encode($this->iv.$final_encryption.$encrypted_data);

        if($output):
            print("Encrypted data: {$output}<br/>");
        else:
            print("Error in encrypting data");
        endif;
    }

    public function decrypt_data($data){
        $this->data = base64_decode($data);
        $this->encryption_type = "AES-256-CBC"; // cipher algorithm
        $this->key = ['6d2d823df2e08c0d3cdf70f148998d49', 'fdb3a18c7b0a322fdb3a18c7b0a320d3'];
        $ivlen = openssl_cipher_iv_length($this->encryption_type);
        $this->iv = substr($this->data, 0, $ivlen);
        $hmac = substr($this->data, $ivlen, $sha2len = 32);
        $decrypt_data = substr($this->data, $ivlen, $sha2len);
        $final_decryption = openssl_decrypt($decrypt_data, $this->encryption_type, $this->key[0], OPENSSL_RAW_DATA, $this->iv);
        $calcmac = hash_hmac('SHA3-512', $decrypt_data, $this->key[1], true);

        if(hash_equals($hmac, $calcmac)):
            print($final_decryption);
        else:
            print("Error in decrypting data");
        endif;
    }
}

$encryption = Encryption();

?> 

谁能帮帮我

【问题讨论】:

  • 欢迎来到 Stackoverflow。您的secured_encryption 提供了3 个元素的输出($this->iv.$final_encryption.$encrypted_data),但是在decrypt_data 上,您不会拆分数据并将完整(Base64 解码)数据提供给o​​penssl_decrypt 和hash_hmac,因此您必须得到解密时出错。
  • 不要发明自己的加密方案。认证加密有成熟的模式,例如GCM
  • @Peter - 我不会说这是他们的加密方案,请参阅encrypt-then-MAC。但我同意,现在像 GCM 这样的模式更方便(和现代),只要它们在各自的环境中得到支持。

标签: php encryption


【解决方案1】:

代码中有几个小问题:

  • secured_encryption 方法中缺少 return 语句。这是错误消息的触发器(hash_equals(): Expected known_string to be a string, bool given),因为$hmac 不包含字符串,而是false。所以在secured_encryption的末尾你必须添加:

    return $output;
    

    这样,加密工作,但解密还没有工作。

  • decrypt_data 中分隔 HMac 时使用了错误的长度。 SHA3​​-512 产生一个 512 位,即 64 字节散列,即:

    $hmac = substr($this->data, $ivlen, $sha2len = 32);
    

    必须替换为:

    $hmac = substr($this->data, $ivlen, $sha2len = 64);   
    
  • 分离数据时,从$ivlen + $sha2len的位置开始,考虑一切到最后,即:

    $decrypt_data = substr($this->data, $ivlen, $sha2len); 
    

    必须替换为:

    $decrypt_data = substr($this->data, $ivlen + $sha2len);
    

通过这些更改,一切正常,输出看起来像像这样:

Encrypted data: uTjcPmLK8jTktJ0oy5AqB40d5YFuAbgXMHfNEM6+JOH+DtyYAhckcv3mkLhdOvUqPlriKqYjHO6cpJI3ZdoTSS4lqDr0eH0MMiUpJMSXcan81irvobcdIV+rvaMPPRj7
Is this safe 

顺便说一句,除了密文之外,IV 也应该经过身份验证,请参阅here。还有提供机密性和身份验证的可验证操作模式,例如GCM(例如aes-256-gcm),s。彼得的评论。您可以通过 openssl_get_cipher_methods() 检查您的环境中可用的算法/模式。

【讨论】:

  • 感谢大家的支持。但仍然有一些问题@Topaco,在完成您要求我做的更改后......我仍然收到错误:- 解密数据出错
  • @Incrediblecoder - 我已经分享了可执行代码here。请检查您的代码是否有差异。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 2011-01-26
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
相关资源
最近更新 更多