简体   繁体   English

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

[英]How to decrypt an encrypted string using openssl_decrypt

I am trying to develop a php program that encrypts some data which can later be decrypted.我正在尝试开发一个 php 程序,该程序可以加密一些以后可以解密的数据。 However, I am having trouble decrypting the data with PHP using AES-256-CBC algorithm by using the openssl_decrypt() method in PHP.但是,我无法通过使用 PHP 中的 openssl_decrypt() 方法使用 AES-256-CBC 算法使用 PHP 解密数据。 The encryption works but when I try to decrypt it gives me an error:-加密有效,但是当我尝试解密时,它给了我一个错误:-
hash_equals(): Expected known_string to be a string, bool given on line 44. hash_equals():期望 known_string 是一个字符串,布尔值在第 44 行给出。

My code below:我的代码如下:

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

?> 

Anybody to help me任何人来帮助我

There are a few minor issues in the code:代码中有几个小问题:

  • There is a return statement missing in the secured_encryption method. secured_encryption方法中缺少 return 语句。 This is the trigger for the error message ( hash_equals(): Expected known_string to be a string, bool given ), since $hmac does not contain a string but is false .这是错误消息的触发器( hash_equals(): Expected known_string to be a string, bool given ),因为$hmac不包含字符串但为false So at the end of secured_encryption you have to add:所以在secured_encryption的末尾你必须添加:

     return $output;

    With this, encryption works, but decryption does not work yet.有了这个,加密工作,但解密还没有工作。

  • When separating the HMac in decrypt_data the wrong length is used.decrypt_data分离HMac 时使用了错误的长度。 SHA3-512 results in a 512 bit, ie 64 byte hash, ie: SHA3​​-512 结果为 512 位,即 64 字节散列,即:

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

    must be replaced by:必须替换为:

     $hmac = substr($this->data, $ivlen, $sha2len = 64);
  • When separating the data, start at the position $ivlen + $sha2len and consider everything to the end, ie:分离数据的时候,从位置$ivlen + $sha2len ,考虑到最后,即:

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

    must be replaced by:必须替换为:

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

With these changes everything works and an output looks eg like this:通过这些更改,一切正常,输出如下所示:

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

By the way, besides the ciphertext also the IV should be authenticated, see here .顺便说一下,除了密文之外,IV 也应该被认证,见这里 There are also authenticatable operation modes that provide confidentiality as well as authentication, eg GCM (eg aes-256-gcm ), s.还有提供机密性和身份验证的可验证操作模式,例如GCM (例如aes-256-gcm ),s。 Peter's comment.彼得的评论。 You can check with openssl_get_cipher_methods() which algorithms/modes are available in your environment.您可以使用openssl_get_cipher_methods()检查您的环境中可用的算法/模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM