openssl_decrypt标签值 [英] openssl_decrypt tag value

查看:50
本文介绍了openssl_decrypt标签值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在网站上使用openssl_encrypt/解密方法,但是$ tag选项有一些麻烦

I'm using the openssl_encrypt / decrypt method in my website but i'm having some troubles with the $tag option

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)时通过引用传递的身份验证标记.但是我不明白.

from http://php.net/manual/en/function.openssl-encrypt.php, the definition of tag is: The authentication tag passed by reference when using AEAD cipher mode (GCM or CCM). But i didn't understand it.

我在我的代码中尝试过

$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

这是正确的.但是如果我直接用这种方式解密加密的文本:

which is correct. but if i directly decrypt the encrypted text this way:

$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的值应该是什么?谢谢

if someone could explain to me why this is happening and what should be the value of $tags. thanks

推荐答案

使用GCM操作模式时,PHP抱怨的标签是AES的重要方面.在这种模式下,不仅会应用AES分组密码,还会计算出身份验证标签.它是代表HMAC的字节数组,可用于验证数据的完整性和解密.需要提供相同的标签来进行验证.有关更多详细信息,请参见有关Galois/Counter Mode的维基百科页面.

The tag that PHP is complaining about is an essential aspect of AES when using GCM mode of operation. In this mode, not only does the AES block cipher get applied, but an authentication tag gets calculated as well. It is an array of bytes that represents an HMAC that can be used to verify the integrity of the data and wen decrypting. That same tag needs to be provided to do that verification. See the Wikipedia page about Galois/Counter Mode for more details.

因此,为了成功地解密该密文,您需要捕获由 openssl_encrypt()调用产生的 $ tag 变量,并将其输入到 openssl_decrypt中()调用.您没有这样做,因此抱怨缺少标签.请注意,标签(通常)包含不可读的字符,因此以base64编码格式存储标签会更加方便.

So in order to successfully decrypt that ciphertext, you need to capture the $tag variable resulting from the openssl_encrypt() invocation and feed it into the openssl_decrypt() invocation. You did not do that, hence the complaint about the missing tag. Note that the tag (typically) contains non-readable characters so it is more convenient to store it in a base64 encoded format.

除了 $ tag 变量外,还应为 openssl_decrypt()方法提供与 $ iv 变量相同的值.就像您在 openssl_encrypt()调用中使用的一样.再次,base64编码使之更加容易.

In addition to the $tag variable, you should also provide the same value for the $iv variable to the openssl_decrypt() method as you used in the openssl_encrypt() invocation. Again, base64 encoding makes that easier.

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

A quick test below demonstrates all this, where I first modified your script to print more stuff and then used the provided script to decrypt:

$ 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");
}

这篇关于openssl_decrypt标签值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆