openssl_decrypt не расшифровывает данные, хранящиеся с помощью openssl_encrypt

Мне нужно простое шифрование/дешифрование для неконфиденциальных данных, которые я не могу хранить в виде обычного текста. Я собрал этот класс, и openssl_decrypt возвращает false, но я не могу понять, почему.

$ssl=new ssl();

$x="this was encrpyted";
echo "<br />1".$x;
$json=$ssl->encrypt($x);
echo "<br />2".$json;
echo "<br />3".$ssl->decrypt($json);

class ssl {

    private $cipher = "aes-128-gcm";
    private $options=0;

    public function encrypt($plaintext) {
        $key=openssl_random_pseudo_bytes(16);
        $ivlen=openssl_cipher_iv_length($this->cipher);
        $iv=openssl_random_pseudo_bytes($ivlen);
        $ciphertext=openssl_encrypt(
            $plaintext, 
            $this->cipher, 
            $key,
            $this->options,
            $iv,
            $tag
        );
        $a=[];
        $a["key"]=bin2hex($key);    
        $a["iv"]=bin2hex($iv);  
        $a["ciphertext"]=$ciphertext;   
        return json_encode($a);
    }

    public function decrypt($json) {
        $a=json_decode($json,true);
        return openssl_decrypt(
            $a["ciphertext"], 
            $this->cipher, 
            hex2bin($a["key"]),
            $this->options,
            hex2bin($a["iv"])
        );
    }

}   

person Corbin    schedule 15.11.2019    source источник
comment
У вас есть какие-либо ошибки или вывод?   -  person Bill Chen    schedule 16.11.2019
comment
Вам почти наверняка лучше использовать для этого более современные встроенные функции.   -  person miken32    schedule 16.11.2019


Ответы (1)


Вы не сохраняете значение тега, возвращенное в процессе шифрования. Как упоминается в документации требуется для шифров GCM и CCM.

Также немного очистил ваш код:

<?php
class Ssl {

    private static $cipher = "aes-128-gcm";
    private static $options=0;

    public static function encrypt(string $plaintext): ?string
    {
        $key        = openssl_random_pseudo_bytes(16);
        $ivlen      = openssl_cipher_iv_length(self::$cipher);
        $iv         = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt(
            $plaintext,
            self::$cipher,
            $key,
            self::$options,
            $iv,
            $tag
        );
        $a = [
            "key"        => bin2hex($key),
            "iv"         => bin2hex($iv),
            "tag"        => bin2hex($tag),
            "ciphertext" => $ciphertext,
        ];
        return json_encode($a);
    }

    public static function decrypt(string $json): ?string
    {
        $a = json_decode($json);
        $result = openssl_decrypt(
            $a->ciphertext,
            self::$cipher,
            hex2bin($a->key),
            self::$options,
            hex2bin($a->iv),
            hex2bin($a->tag)
        );
        if ($result === false) {
            return null;
        }
        return $result;
    }
}

$x = "this was encrpyted";
echo "<br />\n1 $x";
$json = Ssl::encrypt($x);
echo "<br />\n2 $json";
echo "<br />\n3 " . Ssl::decrypt($json);

Выход:

<br />
1 this was encrpyted
<br />
2 {"key":"3b48ecde64b8e2789991604678cc9fb9","iv":"307443dc8d114773fc02d0c4","tag":"8c66a2b0094435345b751b2dec5231a9","ciphertext":"EiIxe2hp0aONf41oBRuvwtjr"}
<br />
3 this was encrpyted
person miken32    schedule 15.11.2019
comment
хранение тегов помогло мне выбраться из этого, спасибо - person Shoyeb Sheikh; 22.07.2021