Php openssl_解密标记值

Php openssl_解密标记值,php,encryption,openssl,Php,Encryption,Openssl,我在我的网站上使用openssl_加密/解密方法,但是我在$tag选项上遇到了一些问题 openssl_encrypt ( $data, $method, $key, $options, $iv, $tag ) openssl_decrypt ( $data, $method, $key, $options, $iv, $tag ) 从中,标记的定义是:使用AEAD密码模式(GCM或CCM)时通过引用传递的身份验证标记。但我不明白 我在密码里试过了 $data = "text to be en

我在我的网站上使用openssl_加密/解密方法,但是我在$tag选项上遇到了一些问题

openssl_encrypt ( $data, $method, $key, $options, $iv, $tag )
openssl_decrypt ( $data, $method, $key, $options, $iv, $tag )
从中,标记的定义是:使用AEAD密码模式(GCM或CCM)时通过引用传递的身份验证标记。但我不明白

我在密码里试过了

$data = "text to be encrypted";
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);

if (in_array($cipher, openssl_get_cipher_methods())){       
    $encryptedData = openssl_encrypt($data,$cipher,$key,$option,$iv,$tag);
    echo $encryptedData;

    $decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
    echo $decryptedData;
}
我得到了这个结果:

encrypted text: Vlx/yKkPhg0DpD0YKvnFKRiCh/I=
decrypted text: text to be encrypted
这是正确的。但是如果我用这种方式直接解密加密文本:

$data = "text to be encrypted";
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);

if (in_array($cipher, openssl_get_cipher_methods())){
    $encryptedData = "Vlx/yKkPhg0DpD0YKvnFKRiCh/I=";

    $decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
    echo $decryptedData;
}
我得到:

Notice: Undefined variable: tag

如果有人能向我解释为什么会发生这种情况,以及$tags的价值应该是多少。谢谢

当使用GCM操作模式时,PHP抱怨的标签是AES的一个重要方面。在这种模式下,不仅应用AES分组密码,还计算身份验证标记。它是一个字节数组,表示可以用于验证数据完整性和解密的HMAC。需要提供相同的标签来进行验证。有关更多详细信息,请参阅

因此,为了成功解密该密文,您需要捕获由
openssl\u encrypt()
调用产生的
$tag
变量,并将其输入
openssl\u decrypt()
调用。你没有那样做,因此对丢失的标签提出了投诉。请注意,标记(通常)包含不可读的字符,因此以base64编码格式存储更方便

除了
$tag
变量外,还应该为
$iv
变量提供与调用
openssl\u encrypt()
方法相同的值。同样,base64编码使这更容易

下面的一个快速测试演示了所有这些,我首先修改了您的脚本以打印更多内容,然后使用提供的脚本进行解密:

$ php test1.php 
iv base64-ed: vBKbi8c6vCyvWonV
plaintext: text to be encrypted
ciphertext base64-ed: z28spOd3UEDmj+3a8n/WK11ls7w=
GCM tag base64-ed: OIAggQCGUbPgmPN6lFjQ8g==
$ php test2.php 
decrypted ciphertext: text to be encrypted
其中
test2.php
的代码如下:

$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$iv = base64_decode("vBKbi8c6vCyvWonV");

if (in_array($cipher, openssl_get_cipher_methods())){       

    $encryptedData = "z28spOd3UEDmj+3a8n/WK11ls7w=";
    $tag = base64_decode("OIAggQCGUbPgmPN6lFjQ8g==");

    $decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
    echo("decrypted ciphertext: ".$decryptedData."\n");
}

谢谢,但如果我理解正确,每次我需要使用aes-128-gcm解密时,我都必须先捕获$tag?使用
$tag
为您提供身份验证。如果不需要,则可以使用“普通”aes-128-ctr模式,通过稍微调整
$iv
进行解密。例如,见。不过,您始终需要捕获
$iv
。是的,我昨天有点搞清楚了,我使用了“aes-256-cbc”,它在没有$tag的情况下工作得非常好。非常感谢