我在我的网站中使用openssl_encrypt /解密方法,但是$ tag选项有一些麻烦
openssl_encrypt ( $data, $method, $key, $options, $iv, $tag )
openssl_decrypt ( $data, $method, $key, $options, $iv, $tag )
从http://php.net/manual/en/function.openssl-encrypt.php开始,标记的定义为:使用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的值应该是多少?谢谢
答案 0 :(得分:0)
当使用GCM操作模式时,PHP抱怨的标签是AES的重要方面。在此模式下,不仅会应用AES分组密码,还会计算出身份验证标签。它是代表HMAC的字节数组,可用于验证数据的完整性和解密。需要提供相同的标签来进行验证。有关更多详细信息,请参见Wikipedia page about Galois/Counter Mode。
因此,为了成功地解密该密文,您需要捕获$tag
调用产生的openssl_encrypt()
变量并将其输入openssl_decrypt()
调用中。您没有这样做,因此抱怨缺少标签。请注意,该标签(通常)包含不可读的字符,因此以base64编码格式存储标签更为方便。
除了$tag
变量之外,还应为$iv
方法中的openssl_decrypt()
变量提供与openssl_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");
}