Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP aes-128-gcm openssl_decrypt仅在使用openssl_encrypt后有效_Php_Encryption_Php Openssl_Aes Gcm - Fatal编程技术网

PHP aes-128-gcm openssl_decrypt仅在使用openssl_encrypt后有效

PHP aes-128-gcm openssl_decrypt仅在使用openssl_encrypt后有效,php,encryption,php-openssl,aes-gcm,Php,Encryption,Php Openssl,Aes Gcm,我必须解密从外部获取的aes-128-gcm加密数据。由于openssl_decrypt从未返回任何数据,所以我自己尝试对其他地方解密的数据进行加密,看看这是否有效,事实上,我收到的加密数据与我尝试解密的数据相同。因此我知道,我所有的参数都是正确的。所以我玩弄了我的PHP代码,得出了一个奇怪的结论,解密数据只对我有效,在我加密明文之后?!? 有人知道这里发生了什么吗 谢谢, 哈利 输出: 普通的: 0F00102D280C07E4081F010103B1000FF8880020C09060006

我必须解密从外部获取的aes-128-gcm加密数据。由于openssl_decrypt从未返回任何数据,所以我自己尝试对其他地方解密的数据进行加密,看看这是否有效,事实上,我收到的加密数据与我尝试解密的数据相同。因此我知道,我所有的参数都是正确的。所以我玩弄了我的PHP代码,得出了一个奇怪的结论,解密数据只对我有效,在我加密明文之后?!? 有人知道这里发生了什么吗

谢谢, 哈利

输出:

普通的: 0F00102D280C07E4081F010103B1000FF8880020C090600061900FF090D3232313230323031323735360904103B1000090507E4081F01604C48DF06000000CB0600008CF06000E61E706000020A0600009000900

附件: 09E89C959CD513057787832142E6796E1F6DE55CBA8E5CEC6E16AA635B3B102DDB22D85841923DDC2EE3052027945DFD00D025A0A5D0EB385E0033DD28037D80B4752B3310B01871474686B609D215864785895DF2BE887

十二月:

十二月二日:
0F00102D280C07E4081F010103B1000FF8880020C09060006190900FF090D3232313230323031323735360904103B1000090507E4081F01604C48DF06000000CB0600008CF06000E61E706000020A060000009000欢迎来到Stackoverflow。您正在GCM模式下使用AES算法,这意味着密文不会被身份验证标记或短标记修改。此标记在使用AES-GCM加密明文时生成,在解密密文时需要可用

在代码中,为decrypt函数提供一个空$tag变量,解密失败。当使用openssl\u加密生成新的明文时,$tag变量将被标记填充。现在再次解密,并将此标记提供给openssl_decrypt-function,解密工作与预期一样

因此,您需要从第三方获取$tag的值,才能成功地将密文解密回明文

使用源代码中的这一小改动,程序将提供$tag:

$decrypted = openssl_decrypt($enc, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "tag: ".bin2hex($tag)."<br>" . PHP_EOL;
$encrypted = openssl_encrypt($plain, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "tag: ".bin2hex($tag)."<br>" . PHP_EOL;
$decrypted2 = openssl_decrypt($enc, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
在第一次运行中,如预期的那样更改您的源代码以解密密码,我将十六进制数据“00000002”手动添加到iv中:

plain:  0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900<br>
enc:    09e89c959cd513057787832142e6796e1f6de55cba8e5cec6e16aa635b3b102ddb22d85841923ddc2ee3052027945dfd00d025a0a5d0eb385e0033dd28037d80b47522b3db310b01871474686b609d2da15864785895df2be887<br>
decCtr: 0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900<br>
decGcm: 0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900
代码:


欢迎来到Stackoverflow。您正在GCM模式下使用AES算法,这意味着密文不会被身份验证标记或短标记修改。此标记在使用AES-GCM加密明文时生成,在解密密文时需要可用

在代码中,为decrypt函数提供一个空$tag变量,解密失败。当使用openssl\u加密生成新的明文时,$tag变量将被标记填充。现在再次解密,并将此标记提供给openssl_decrypt-function,解密工作与预期一样

因此,您需要从第三方获取$tag的值,才能成功地将密文解密回明文

使用源代码中的这一小改动,程序将提供$tag:

$decrypted = openssl_decrypt($enc, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "tag: ".bin2hex($tag)."<br>" . PHP_EOL;
$encrypted = openssl_encrypt($plain, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "tag: ".bin2hex($tag)."<br>" . PHP_EOL;
$decrypted2 = openssl_decrypt($enc, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
在第一次运行中,如预期的那样更改您的源代码以解密密码,我将十六进制数据“00000002”手动添加到iv中:

plain:  0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900<br>
enc:    09e89c959cd513057787832142e6796e1f6de55cba8e5cec6e16aa635b3b102ddb22d85841923ddc2ee3052027945dfd00d025a0a5d0eb385e0033dd28037d80b47522b3db310b01871474686b609d2da15864785895df2be887<br>
decCtr: 0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900<br>
decGcm: 0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900
代码:


这就解释了PHP的行为。但原始加密根据DLMS/COSEM绿皮书第9.2.7.2.4段进行,AES-GCM仅支持认证、仅加密和加密+认证。因此,在EncPytion-only模式下,不需要任何标记,并将其定义为填充00的12字节->因此我的空$tag值,因为$tag=hex2在'000000000000000000000000000000'中没有任何区别。太棒了!我已经怀疑它可能可以用CTR模式解决,但是没有找到额外IV字节的信息。这解释了PHP的行为。但原始加密根据DLMS/COSEM绿皮书第9.2.7.2.4段进行,AES-GCM仅支持认证、仅加密和加密+认证。因此,在EncPytion-only模式下,不需要任何标记,并将其定义为填充00的12字节->因此我的空$tag值,因为$tag=hex2在'000000000000000000000000000000'中没有任何区别。太棒了!我已经怀疑它可能可以解决与CTR模式,但不会找到额外的IV字节的信息。
plain:  0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900<br>
enc:    09e89c959cd513057787832142e6796e1f6de55cba8e5cec6e16aa635b3b102ddb22d85841923ddc2ee3052027945dfd00d025a0a5d0eb385e0033dd28037d80b47522b3db310b01871474686b609d2da15864785895df2be887<br>
decCtr: 0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900<br>
decGcm: 0f00102d280c07e4081f01103b1000ff8880020c09060006190900ff090d323232313230323031323735360904103b1000090507e4081f0106004c48df06000000cb06000089cf06000e61e7060000020a060000000009000900
<?php
$method='aes-128-gcm';
$key = hex2bin('0748BEF58E04D5917ED0B9B558628265');
$iv = hex2bin('534D5367700114E600102D29');
$tag = NULL;
$enc = hex2bin('09E89C959CD513057787832142E6796E1F6DE55CBA8E5CEC6E16AA635B3B102DDB22D85841923DDC2EE3052027945DFD00D025A0A5D0EB385E0033DD28037D80B47522B3DB310B01871474686B609D2DA15864785895DF2BE887');
$plain = hex2bin('0F00102D280C07E4081F01103B1000FF8880020C09060006190900FF090D323232313230323031323735360904103B1000090507E4081F0106004C48DF06000000CB06000089CF06000E61E7060000020A060000000009000900');

//$decrypted = openssl_decrypt($enc, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
$methodCtr = 'aes-128-ctr';
$ivCtr = hex2bin('534D5367700114E600102D2900000002');
$decryptedCtr = openssl_decrypt($enc, $methodCtr, $key, OPENSSL_RAW_DATA, $ivCtr);
$encrypted = openssl_encrypt($plain, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);
echo "tag: ".bin2hex($tag)."<br>" . PHP_EOL;
$decryptedGcm = openssl_decrypt($enc, $method, $key, OPENSSL_RAW_DATA, $iv, $tag);

echo "plain:  ".bin2hex($plain)."<br>" . PHP_EOL;
echo "enc:    ".bin2hex($encrypted)."<br>" . PHP_EOL;
echo "decCtr: ".bin2hex($decryptedCtr)."<br>" . PHP_EOL;
echo "decGcm: ".bin2hex($decryptedGcm)."\n" . PHP_EOL;
while ($msg = openssl_error_string())
    echo $msg . "<br>\n";
?>