如何使用openssl_decrypt解密加密的字符串

时间:2020-09-17 21:37:29

标签: php encryption

我正在尝试开发一个php程序,该程序可以对某些数据进行加密,然后可以将其解密。但是,我在使用PHP中的openssl_decrypt()方法时无法使用AES-256-CBC算法使用PHP解密数据。加密有效,但是当我尝试解密时,出现错误:-
hash_equals():期望known_string是一个字符串,在第44行给出bool。

我的下面的代码:

<?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();

?> 

任何可以帮助我的人

1 个答案:

答案 0 :(得分:3)

代码中有一些小问题:

  • secured_encryption方法中缺少返回语句。这是错误消息的触发原因( hash_equals():期望的known_string为字符串,给定布尔值),因为$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),彼得的评论。您可以使用openssl_get_cipher_methods()来检查环境中可用的算法/模式。