最新的 PHP 中的 AES GCM 是否已损坏,还是我做错了什么?

我尝试使用 openssl_encrypt/decrypt 在 PHP 中实现加密。我尝试在 GCM 模式下使用 128 位 AES,但后来我注意到即使是 GCM 标签的一个字节也足以成功解密。


我用谷歌搜索了一下,发现这个 crypto.stackexchange 问题遇到了同样的问题。我再次问的问题是,这已经超过 1 年了,而且在最新版本上似乎仍未修复。我在 2019 年 5 月 28 日使用 OpenSSL 1.1.1c 的 PHP 版本 7.3.9-1 上检查了这个。


这是我的代码。


$key = 'is_gcm_really_broken_on_php'; //27 bytes ... only need 16 but openssl doesnt use rest automatically. thats ok

$iv = openssl_random_pseudo_bytes(16);

$tag = null;

$toEncrypt = 'hello world';

$encrypted = openssl_encrypt($toEncrypt, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);

echo 'tag is ' . strlen($tag) . ' bytes<br>';

$encodedMsg = base64_encode($iv.$tag.$encrypted);

var_dump($encodedMsg);


//.... decrypting

echo '<br><br>decrypting<br>';


$decodedMsg = base64_decode($encodedMsg);

$msgIv = substr($decodedMsg, 0, 16);

$msgTag = substr($decodedMsg, 16, 1);

echo 'using tag thats ' . strlen($msgTag) . ' bytes<br>';

$msgToDecrypt = substr($decodedMsg, 32);

$decrypted = openssl_decrypt($msgToDecrypt, 'aes-128-gcm', $key, OPENSSL_RAW_DATA, $msgIv, $msgTag);

echo 'decryption is ok.. no error<br>decrypted message is ' . $decrypted;

代码是否正常并且 PHP 在这件事上仍然不安全(这有点疯狂,因为文档中没有关于它的警告)?还是代码错了?


临摹微笑
浏览 284回答 1
1回答

HUH函数

您的代码还可以,而且 PHP 是安全的这里的问题是您如何使用 AES-GCM。标签长度是一个安全参数,这意味着您可以选择任何大小。最小推荐大小为 96 位,您应该检查大小。在您的代码中,您不检查标签大小,openssl_decrypt()而是按照您的要求执行:验证 1 字节标签。PHP 会知道这是否中断,请参阅测试第 31 行最后的想法:使用低级密码时要小心,你可以使用嵌入PHP>7.2的Sodium
打开App,查看更多内容
随时随地看视频慕课网APP