openssl_decrypt 未解密使用 openssl_encrypt 存储的数据

openssl_decrypt not decrypting data stored with openssl_encrypt

我需要一个简单的 encrypt/decrypt 来存储我无法存储为纯文本的非敏感数据。我把这个 class 和 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"])
        );
    }

}   

您没有存储从加密过程返回的标记值。正如 mentioned in the documentation,这是 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