Como descriptografar uma string criptografada usando openssl_decrypt

Sep 18 2020

Estou tentando desenvolver um programa php que criptografa alguns dados que podem ser descriptografados posteriormente. No entanto, estou tendo problemas para descriptografar os dados com PHP usando o algoritmo AES-256-CBC usando o método openssl_decrypt () em PHP. A criptografia funciona, mas quando tento descriptografá-la, ocorre um erro: -
hash_equals (): Cadeia_conhecida esperada para ser uma string, bool fornecido na linha 44.

Meu código abaixo:

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

?> 

Alguém para me ajudar

Respostas

3 Topaco Sep 18 2020 at 15:19

Existem alguns pequenos problemas no código:

  • Há uma instrução de retorno ausente no secured_encryptionmétodo. Este é o gatilho para a mensagem de erro ( hash_equals (): Cadeia_conhecida esperada para ser uma cadeia, dado bool ), uma vez $hmacque não contém uma cadeia, mas é false. Portanto, no final, secured_encryptionvocê deve adicionar:

    return $output;
    

    Com isso, a criptografia funciona, mas a descriptografia ainda não funciona.

  • Ao separar o HMac no decrypt_datacomprimento errado é usado. SHA3-512 resulta em 512 bits, ou seja, hash de 64 bytes, ou seja:

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

    deve ser substituído por:

    $hmac = substr($this->data, $ivlen, $sha2len = 64);   
    
  • Ao separar os dados, comece na posição $ivlen + $sha2lene considere tudo até o final, ou seja:

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

    deve ser substituído por:

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

Com essas mudanças, tudo funciona e uma saída fica assim:

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

Aliás, além do texto cifrado também o IV deve ser autenticado, veja aqui . Existem também modos de operação autenticáveis ​​que fornecem confidencialidade e autenticação, por exemplo, GCM (por exemplo aes-256-gcm), s. Comentário de Peter. Você pode verificar openssl_get_cipher_methods()quais algoritmos / modos estão disponíveis em seu ambiente.